23#if COAP_OSCORE_SUPPORT
26#define AAD_BUF_LEN 200
31#if COAP_CLIENT_SUPPORT
39 coap_log_warn(
"OSCORE: Recipient ID must be defined for a client\n");
47 if (id_context ==
NULL) {
58 osc_ctx = coap_oscore_init(session->
context, oscore_conf);
59 if (osc_ctx ==
NULL) {
63 session->oscore_encryption = 1;
153 oscore_conf, app_data, callback, ws_host);
172 app_data, callback, ws_host);
214 oscore_conf, app_data, callback, ws_host);
233 app_data, callback, ws_host);
245#if COAP_SERVER_SUPPORT
264 osc_ctx = coap_oscore_init(context, oscore_conf);
278 uint8_t option_value_buffer[15];
286 memset(&uri, 0,
sizeof(uri));
308 sizeof(option_value_buffer),
310 option_value_buffer))
343#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_OSCORE
398 uint8_t pdu_code = pdu->
code;
401 uint8_t *ciphertext_buffer =
NULL;
402 size_t ciphertext_len = 0;
403 uint8_t aad_buffer[AAD_BUF_LEN];
404 uint8_t nonce_buffer[13];
410 uint8_t group_flag = 0;
412 int doing_observe = 0;
413 uint32_t observe_value = 0;
416 uint8_t external_aad_buffer[200];
418 uint8_t oscore_option[255];
419 ssize_t oscore_option_len;
446 rcp_ctx = session->recipient_ctx;
458 if (association ==
NULL)
470 if (coap_request || doing_observe ||
472 uint8_t partial_iv_buffer[8];
473 size_t partial_iv_len;
476 sizeof(partial_iv_buffer),
478 if (snd_ctx->
seq == 0) {
480 partial_iv_buffer[0] =
'\000';
483 partial_iv.
s = partial_iv_buffer;
484 partial_iv.
length = partial_iv_len;
495 if (coap_request || doing_observe ||
506 nonce.
s = nonce_buffer;
544 if (oscore_option_len < 0) {
580 external_aad.
s = external_aad_buffer;
587 sizeof(external_aad_buffer));
588 if (external_aad.
length == 0)
600 assert(aad.
length < AAD_BUF_LEN);
614 if (plain_pdu ==
NULL)
728 dump_cose(cose,
"Pre encrypt");
731 if (ciphertext_buffer ==
NULL)
736 if ((
int)ciphertext_len <= 0) {
737 coap_log_warn(
"OSCORE: Encryption Failure, result code: %d \n",
738 (
int)ciphertext_len);
741 assert(ciphertext_len < OSCORE_CRYPTO_BUFFER_SIZE);
751 if (!
coap_add_data(osc_pdu, ciphertext_len, ciphertext_buffer))
755 ciphertext_buffer =
NULL;
785 if (doing_observe && observe_value == 1) {
830 if (ciphertext_buffer)
841 const char *diagnostic,
844 int encrypt_oscore) {
847 int oscore_encryption = session->oscore_encryption;
848 unsigned char buf[4];
856 (diagnostic ? strlen(diagnostic) : 0));
862 }
else if (kid_context ==
NULL) {
869 coap_add_data(err_pdu, strlen(diagnostic), (
const uint8_t *)diagnostic);
870 session->oscore_encryption = encrypt_oscore;
872 if ((echo_data || kid_context) && encrypt_oscore) {
880 session->oscore_encryption = 0;
889 session->oscore_encryption = oscore_encryption;
898 if (oscore_ctx ==
NULL) {
921 const uint8_t *osc_value;
927 uint8_t aad_buffer[AAD_BUF_LEN];
928 uint8_t nonce_buffer[13];
932 int got_resp_piv = 0;
933 int doing_resp_observe = 0;
942 uint8_t external_aad_buffer[100];
945#if COAP_CLIENT_SUPPORT
980 if (decrypt_pdu ==
NULL) {
1047 uint64_t incoming_seq;
1054 coap_log_warn(
"OSCORE: OSCORE Option cannot be decoded.\n");
1055 build_and_send_error_pdu(session,
1058 "Failed to decode COSE",
1077 session->oscore_r2 != 0 ? (uint8_t *)&session->oscore_r2 :
NULL,
1087 if (kid_context.
length > length)
1094 kid_context.
s = ptr;
1097 if (session->oscore_r2 != 0) {
1116 if (osc_ctx ==
NULL)
1136 build_and_send_error_pdu(session,
1139 "Security context not found",
1159 build_and_send_error_pdu(session,
1180 coap_log_warn(
"OSCORE: OSCORE Option cannot be decoded.\n");
1193#if COAP_CLIENT_SUPPORT
1204 if (kid_context.
length > length)
1211 kid_context.
s = ptr;
1242 coap_log_crit(
"OSCORE: Security Context association not found\n");
1277 external_aad.
s = external_aad_buffer;
1283 external_aad_buffer,
1284 sizeof(external_aad_buffer));
1285 if (external_aad.
length == 0)
1294 sizeof(aad_buffer));
1297 assert(aad.
length < AAD_BUF_LEN);
1309 nonce.
s = nonce_buffer;
1320 association->
nonce =
1352 decrypt_request_association =
1378 coap_log_warn(
"OSCORE Replay protection, SEQ larger than SEQ_MAX.\n");
1390 nonce.
s = nonce_buffer;
1394#ifdef OSCORE_EXTRA_DEBUG
1395 dump_cose(cose,
"!req post set nonce");
1427#ifdef OSCORE_EXTRA_DEBUG
1428 dump_cose(cose,
"!req pre aad");
1430 external_aad.
s = external_aad_buffer;
1436 external_aad_buffer,
1437 sizeof(external_aad_buffer));
1438 if (external_aad.
length == 0)
1447 sizeof(aad_buffer));
1450 assert(aad.
length < AAD_BUF_LEN);
1452#ifdef OSCORE_EXTRA_DEBUG
1453 dump_cose(cose,
"!req post set aad");
1468 st_encrypt = pdu->
data;
1470 if (encrypt_len <= 0) {
1482 if (encrypt_len <= tag_len) {
1487 build_and_send_error_pdu(session,
1490 "Decryption failed",
1495 decrypt_request_association =
NULL;
1505 if (plain_pdu ==
NULL) {
1526 plain_pdu->
used_size = encrypt_len - tag_len;
1528 dump_cose(cose,
"Pre decrypt");
1531 if (pltxt_size <= 0) {
1532 coap_log_warn(
"OSCORE: Decryption Failure, result code: %d \n",
1535 build_and_send_error_pdu(session,
1538 "Decryption failed",
1543 decrypt_request_association =
NULL;
1556 session->
context->oscore_update_seq_num_cb !=
NULL) {
1565 assert((
size_t)pltxt_size < pdu->alloc_size + pdu->
max_hdr_size);
1582 coap_prng_lkd(&session->oscore_r2,
sizeof(session->oscore_r2));
1583 memcpy(kc->
s, &session->oscore_r2,
sizeof(session->oscore_r2));
1584 memcpy(&kc->
s[
sizeof(session->oscore_r2)],
1591 oscore_r2.
length =
sizeof(session->oscore_r2);
1592 oscore_r2.
s = (
const uint8_t *)&session->oscore_r2;
1594 build_and_send_error_pdu(session,
1601 decrypt_request_association =
NULL;
1604#if COAP_CLIENT_SUPPORT
1611 coap_log_warn(
"OSCORE Appendix B.2: Expected 4.01 response\n");
1649 if (!session->b_2_retransmit_token) {
1653 if (coap_retransmit_oscore_pdu(session, sent_pdu,
NULL) ==
1661#if COAP_SERVER_SUPPORT
1673 build_and_send_error_pdu(session,
1681 decrypt_request_association =
NULL;
1683 if (session->
context->oscore_update_seq_num_cb !=
NULL) {
1703 build_and_send_error_pdu(session,
1710 decrypt_request_association =
NULL;
1724 decrypt_pdu->
code = plain_pdu->
token[0];
1732 switch (opt_iter.
number) {
1736 if (!coap_request) {
1750 doing_resp_observe = 1;
1773 if (!coap_request && !doing_resp_observe) {
1808 if (session->b_2_retransmit_token) {
1810 session->b_2_retransmit_token->s);
1812 session->b_2_retransmit_token =
NULL;
1815#if COAP_CLIENT_SUPPORT
1828 sent_pdu = lg_crcv->sent_pdu;
1836 if (coap_retransmit_oscore_pdu(session, sent_pdu, opt) !=
COAP_INVALID_MID) {
1837 session->doing_b_1_2 = 1;
1841 }
else if (session->doing_b_1_2) {
1846 coap_update_token(decrypt_pdu, lg_crcv->app_token->length, lg_crcv->app_token->s);
1849 session->doing_b_1_2 = 0;
1852 if (association && association->
is_observe == 0)
1859 if (decrypt_request_association) {
1861 decrypt_request_association =
NULL;
1863 if (association && association->
is_observe == 0)
1871 COAP_ENC_ASCII = 0x001,
1872 COAP_ENC_HEX = 0x002,
1873 COAP_ENC_CONFIG = 0x0200,
1874 COAP_ENC_INTEGER = 0x400,
1875 COAP_ENC_TEXT = 0x800,
1876 COAP_ENC_BOOL = 0x1000,
1877 COAP_ENC_UNSIGNED64 = 0x2000,
1879} coap_oscore_coding_t;
1882#define TEXT_MAPPING(t, v) \
1883 { { sizeof(#t)-1, (const uint8_t *)#t }, v }
1885static struct coap_oscore_encoding_t {
1887 coap_oscore_coding_t encoding;
1888} oscore_encoding[] = {
1889 TEXT_MAPPING(ascii, COAP_ENC_ASCII),
1890 TEXT_MAPPING(hex, COAP_ENC_HEX),
1891 TEXT_MAPPING(config, COAP_ENC_CONFIG),
1892 TEXT_MAPPING(integer, COAP_ENC_INTEGER),
1893 TEXT_MAPPING(unsigned64, COAP_ENC_UNSIGNED64),
1894 TEXT_MAPPING(text, COAP_ENC_TEXT),
1895 TEXT_MAPPING(
bool, COAP_ENC_BOOL),
1896 {{0,
NULL}, COAP_ENC_LAST}
1900 coap_oscore_coding_t encoding;
1901 const char *encoding_name;
1904 uint64_t value_int64;
1915hex_to_char(
char c, uint8_t *value) {
1916 if (
'a' <= c && c <=
'f') {
1917 *value = c -
'a' + 10;
1918 }
else if (
'A' <= c && c <=
'F') {
1919 *value = c -
'A' + 10;
1920 }
else if (
'0' <= c && c <=
'9') {
1931parse_hex_bin(
const char *begin,
const char *end) {
1939 for (i = 0; (i < (size_t)(end - begin)); i++) {
1940 while ((i < (
size_t)(end - begin)) &&
1941 (begin[i] ==
'\r' || begin[i] ==
'\n' || begin[i] ==
' ')) {
1944 if (i == (
size_t)(end - begin))
1946 if (isxdigit((uint8_t)begin[i])) {
1949 if (!hex_to_char(begin[i], &value)) {
1952 binary->
s[o] = value << 4;
1954 while ((i < (
size_t)(end - begin)) &&
1955 (begin[i] ==
'\r' || begin[i] ==
'\n' || begin[i] ==
' ')) {
1958 if (i == (
size_t)(end - begin))
1960 if (!hex_to_char(begin[i], &value)) {
1963 binary->
s[o++] += value;
1968 if (i != (
size_t)(end - begin))
1984get_split_entry(
const char **start,
1987 oscore_value_t *value,
1989 const char *begin = *start;
1990 const char *keep_start = *start;
2000 kend = end = memchr(begin,
'\n', size);
2005 if ((tend = memchr(begin,
'"', end - begin))) {
2007 if (!memchr(tend + 1,
'"', end - tend -1)) {
2009 kend = end = memchr(end,
'"', size - (end - begin));
2012 kend = end = memchr(kend,
'\n', size - (kend - begin));
2020 if (end > begin && end[-1] ==
'\r')
2023 if (begin[0] ==
'#' || (end - begin) == 0) {
2025 size -= kend - begin + 1;
2027 keep_start = *start;
2032 split = memchr(begin,
',', end - begin);
2036 keyword->
s = (
const uint8_t *)begin;
2037 keyword->
length = split - begin;
2040 if ((end - begin) == 0)
2043 split = memchr(begin,
',', end - begin);
2047 for (i = 0; oscore_encoding[i].name.s; i++) {
2051 value->encoding = oscore_encoding[i].encoding;
2052 value->encoding_name = (
const char *)oscore_encoding[i].name.s;
2056 if (oscore_encoding[i].name.s ==
NULL)
2060 if ((end - begin) == 0)
2063 if (value->encoding == COAP_ENC_CONFIG && begin[0] ==
'\'') {
2064 split = memchr(&begin[1],
'\'', size - (begin - keep_start) - 1);
2067 end = memchr(split,
'\n', size - (split - keep_start));
2074 if (begin[0] ==
'"') {
2075 split = memchr(&begin[1],
'"', end - split - 1);
2082 switch (value->encoding) {
2083 case COAP_ENC_CONFIG:
2084 case COAP_ENC_ASCII:
2085 value->u.value_bin =
2087 if (value->u.value_bin ==
NULL)
2092 value->u.value_bin = parse_hex_bin(begin, end);
2093 if (value->u.value_bin ==
NULL)
2096 case COAP_ENC_INTEGER:
2097 value->u.value_int = atoi(begin);
2099 case COAP_ENC_UNSIGNED64: {
2100 value->u.value_int64 = strtoull(begin,
NULL, 10);
2104 value->u.value_str.s = (
const uint8_t *)begin;
2105 value->u.value_str.length = end - begin;
2108 len = (size_t)(end - begin);
2109 if (len == 4 && memcmp(
"true", begin, len) == 0)
2110 value->u.value_int = 1;
2111 else if (len == 5 && memcmp(
"false", begin, len) == 0)
2112 value->u.value_int = 0;
2123 coap_log_warn(
"oscore_conf: Unrecognized configuration entry '%.*s'\n",
2131#define CONFIG_ENTRY(n, e, t) \
2132 { { sizeof(#n)-1, (const uint8_t *)#n }, e, \
2133 offsetof(coap_oscore_conf_t, n), t }
2135#undef CONFIG_SND_ENTRY
2136#define CONFIG_SND_ENTRY(n, e, t) \
2137 { { sizeof(#n)-1, (const uint8_t *)#n }, e, \
2138 offsetof(coap_oscore_snd_conf_t, n), t }
2140#undef CONFIG_RCP_ENTRY
2141#define CONFIG_RCP_ENTRY(n, e, t) \
2142 { { sizeof(#n)-1, (const uint8_t *)#n }, e, \
2143 offsetof(coap_oscore_rcp_conf_t, n), t }
2145#undef CONFIG_DUMMY_ENTRY
2146#define CONFIG_DUMMY_ENTRY(n, e, t) \
2147 { { sizeof(#n)-1, (const uint8_t *)#n }, e, 0, t }
2149typedef struct oscore_text_mapping_t {
2152} oscore_text_mapping_t;
2155static oscore_text_mapping_t text_aead_alg[] = {
2161static oscore_text_mapping_t text_hkdf_alg[] = {
2166typedef struct oscore_config_t {
2168 coap_oscore_coding_t encoding;
2170 oscore_text_mapping_t *text_mapping;
2173static oscore_config_t oscore_config[] = {
2174 CONFIG_ENTRY(aead_alg, COAP_ENC_INTEGER | COAP_ENC_TEXT, text_aead_alg),
2175 CONFIG_ENTRY(hkdf_alg, COAP_ENC_INTEGER | COAP_ENC_TEXT, text_hkdf_alg),
2176 CONFIG_ENTRY(master_secret, COAP_ENC_HEX | COAP_ENC_ASCII,
NULL),
2177 CONFIG_ENTRY(master_salt, COAP_ENC_HEX | COAP_ENC_ASCII,
NULL),
2178 CONFIG_ENTRY(id_context, COAP_ENC_HEX | COAP_ENC_ASCII,
NULL),
2180 CONFIG_DUMMY_ENTRY(sender_id, COAP_ENC_HEX | COAP_ENC_ASCII,
NULL),
2182 CONFIG_DUMMY_ENTRY(recipient_id, COAP_ENC_HEX | COAP_ENC_ASCII,
NULL),
2184 CONFIG_ENTRY(replay_window, COAP_ENC_INTEGER,
NULL),
2185 CONFIG_ENTRY(ssn_freq, COAP_ENC_INTEGER,
NULL),
2186 CONFIG_ENTRY(rfc8613_b_1_2, COAP_ENC_BOOL,
NULL),
2187 CONFIG_ENTRY(rfc8613_b_2, COAP_ENC_BOOL,
NULL),
2188 CONFIG_ENTRY(break_sender_key, COAP_ENC_BOOL,
NULL),
2189 CONFIG_ENTRY(break_recipient_key, COAP_ENC_BOOL,
NULL),
2190 CONFIG_DUMMY_ENTRY(complex_sender, COAP_ENC_CONFIG,
NULL),
2191 CONFIG_DUMMY_ENTRY(complex_recipient, COAP_ENC_CONFIG,
NULL),
2194static oscore_config_t oscore_snd_config[] = {
2195 CONFIG_SND_ENTRY(sender_id, COAP_ENC_HEX | COAP_ENC_ASCII,
NULL),
2198static oscore_config_t oscore_rcp_config[] = {
2199 CONFIG_RCP_ENTRY(recipient_id, COAP_ENC_HEX | COAP_ENC_ASCII,
NULL),
2200 CONFIG_RCP_ENTRY(silent_server, COAP_ENC_BOOL,
NULL),
2201 CONFIG_DUMMY_ENTRY(last_seq, COAP_ENC_UNSIGNED64,
NULL),
2202 CONFIG_DUMMY_ENTRY(sliding_window, COAP_ENC_UNSIGNED64,
NULL),
2208 if (snd_conf ==
NULL)
2218 if (rcp_conf ==
NULL)
2229 if (oscore_conf ==
NULL)
2242 rcp_conf = rcp_next;
2251 const char *start = (
const char *)conf_mem.
s;
2252 const char *end = start + conf_mem.length;
2254 oscore_value_t value;
2258 if (snd_conf ==
NULL)
2262 memset(&value, 0,
sizeof(value));
2264 while (end > start &&
2265 get_split_entry(&start, end - start, &keyword, &value, 0) > 0) {
2269 for (i = 0; i <
sizeof(oscore_snd_config) /
sizeof(oscore_snd_config[0]); i++) {
2271 value.encoding & oscore_snd_config[i].encoding) {
2274 switch (value.encoding) {
2276 case COAP_ENC_ASCII:
2277 memcpy(&unused_check,
2278 &(((
char *)snd_conf)[oscore_snd_config[i].offset]),
2279 sizeof(unused_check));
2280 if (unused_check !=
NULL) {
2281 coap_log_warn(
"oscore_snd_conf: Keyword '%.*s' duplicated\n",
2283 (
const char *)keyword.
s);
2287 memcpy(&(((
char *)snd_conf)[oscore_snd_config[i].offset]),
2289 sizeof(value.u.value_bin));
2291 case COAP_ENC_INTEGER:
2293 memcpy(&(((
char *)snd_conf)[oscore_snd_config[i].offset]),
2295 sizeof(value.u.value_int));
2298 for (j = 0; oscore_snd_config[i].text_mapping[j].text.s !=
NULL; j++) {
2299 if (memcmp(value.u.value_str.s,
2300 oscore_snd_config[i].text_mapping[j].text.s,
2301 value.u.value_str.length) == 0) {
2302 memcpy(&(((
char *)snd_conf)[oscore_snd_config[i].offset]),
2303 &oscore_snd_config[i].text_mapping[j].value,
2304 sizeof(oscore_snd_config[i].text_mapping[j].value));
2308 if (oscore_snd_config[i].text_mapping[j].text.s ==
NULL) {
2309 coap_log_warn(
"oscore_snd_conf: Keyword '%.*s': value '%.*s' unknown\n",
2311 (
const char *)keyword.
s,
2312 (
int)value.u.value_str.length,
2313 (
const char *)value.u.value_str.s);
2317 case COAP_ENC_CONFIG:
2318 case COAP_ENC_UNSIGNED64:
2327 if (i ==
sizeof(oscore_snd_config) /
sizeof(oscore_snd_config[0])) {
2328 coap_log_warn(
"oscore_snd_conf: Keyword '%.*s', type '%s' unknown\n",
2330 (
const char *)keyword.
s,
2331 value.encoding_name);
2332 if (value.encoding == COAP_ENC_HEX || value.encoding == COAP_ENC_ASCII ||
2333 value.encoding == COAP_ENC_CONFIG)
2338 if (!snd_conf->sender_id) {
2342 if (snd_conf->sender_id->length > 7) {
2343 coap_log_warn(
"oscore_snd_conf: Maximum size of sender_id is 7 bytes\n");
2355 const char *start = (
const char *)conf_mem.
s;
2356 const char *end = start + conf_mem.length;
2358 oscore_value_t value;
2362 if (rcp_conf ==
NULL)
2366 memset(&value, 0,
sizeof(value));
2368 while (end > start &&
2369 get_split_entry(&start, end - start, &keyword, &value, 0) > 0) {
2373 for (i = 0; i <
sizeof(oscore_rcp_config) /
sizeof(oscore_rcp_config[0]); i++) {
2375 value.encoding & oscore_rcp_config[i].encoding) {
2377 rcp_conf->
last_seq = value.u.value_int64;
2385 switch (value.encoding) {
2387 case COAP_ENC_ASCII:
2388 memcpy(&unused_check,
2389 &(((
char *)rcp_conf)[oscore_rcp_config[i].offset]),
2390 sizeof(unused_check));
2391 if (unused_check !=
NULL) {
2392 coap_log_warn(
"oscore_rcp_conf: Keyword '%.*s' duplicated\n",
2394 (
const char *)keyword.
s);
2398 memcpy(&(((
char *)rcp_conf)[oscore_rcp_config[i].offset]),
2400 sizeof(value.u.value_bin));
2402 case COAP_ENC_INTEGER:
2404 memcpy(&(((
char *)rcp_conf)[oscore_rcp_config[i].offset]),
2406 sizeof(value.u.value_int));
2409 for (j = 0; oscore_rcp_config[i].text_mapping[j].text.s !=
NULL; j++) {
2410 if (memcmp(value.u.value_str.s,
2411 oscore_rcp_config[i].text_mapping[j].text.s,
2412 value.u.value_str.length) == 0) {
2413 memcpy(&(((
char *)rcp_conf)[oscore_rcp_config[i].offset]),
2414 &oscore_rcp_config[i].text_mapping[j].value,
2415 sizeof(oscore_rcp_config[i].text_mapping[j].value));
2419 if (oscore_rcp_config[i].text_mapping[j].text.s ==
NULL) {
2420 coap_log_warn(
"oscore_rcp_conf: Keyword '%.*s': value '%.*s' unknown\n",
2422 (
const char *)keyword.
s,
2423 (
int)value.u.value_str.length,
2424 (
const char *)value.u.value_str.s);
2428 case COAP_ENC_CONFIG:
2429 case COAP_ENC_UNSIGNED64:
2439 if (i ==
sizeof(oscore_rcp_config) /
sizeof(oscore_rcp_config[0])) {
2440 coap_log_warn(
"oscore_rcp_conf: Keyword '%.*s', type '%s' unknown\n",
2442 (
const char *)keyword.
s,
2443 value.encoding_name);
2444 if (value.encoding == COAP_ENC_HEX || value.encoding == COAP_ENC_ASCII ||
2445 value.encoding == COAP_ENC_CONFIG)
2450 if (!rcp_conf->recipient_id) {
2451 coap_log_warn(
"oscore_rcp_conf: recipient_id not defined\n");
2454 if (rcp_conf->recipient_id->length > 7) {
2455 coap_log_warn(
"oscore_rcp_conf: Maximum size of recipient_id is 7 bytes\n");
2467 const char *start = (
const char *)conf_mem.
s;
2468 const char *end = start + conf_mem.length;
2470 oscore_value_t value;
2475 if (oscore_conf ==
NULL)
2479 memset(&value, 0,
sizeof(value));
2492 while (end > start &&
2493 (split_ok = get_split_entry(&start, end - start, &keyword, &value, 0)) > 0) {
2497 for (i = 0; i <
sizeof(oscore_config) /
sizeof(oscore_config[0]); i++) {
2499 value.encoding & oscore_config[i].encoding) {
2501 if (value.u.value_bin->length > 7) {
2502 coap_log_warn(
"oscore_conf: Maximum size of sender_id is 7 bytes\n");
2503 goto error_free_value_bin;
2505 if (oscore_conf->
sender) {
2507 goto error_free_value_bin;
2510 if (!oscore_conf->
sender)
2511 goto error_free_value_bin;
2518 if (value.u.value_bin->length > 7) {
2519 coap_log_warn(
"oscore_conf: Maximum size of recipient_id is 7 bytes\n");
2520 goto error_free_value_bin;
2525 goto error_free_value_bin;
2534 switch (value.encoding) {
2535 case COAP_ENC_CONFIG:
2536 if (keyword.
length ==
sizeof(
"complex_sender") - 1 &&
2537 memcmp(keyword.
s,
"complex_sender", keyword.
length) == 0) {
2539 coap_parse_oscore_snd_conf_mem(*value.u.value_bin);
2544 (
const char *)keyword.
s);
2545 goto error_free_value_bin;
2547 if (oscore_conf->
sender) {
2550 goto error_free_value_bin;
2552 oscore_conf->
sender = snd_conf;
2556 if (keyword.
length ==
sizeof(
"complex_recipient") - 1 &&
2557 memcmp(keyword.
s,
"complex_recipient", keyword.
length) == 0) {
2559 coap_parse_oscore_rcp_conf_mem(*value.u.value_bin);
2564 (
const char *)keyword.
s);
2565 goto error_free_value_bin;
2572 case COAP_ENC_ASCII:
2574 memcpy(&unused_check,
2575 &(((
char *)oscore_conf)[oscore_config[i].offset]),
2576 sizeof(unused_check));
2577 if (unused_check !=
NULL) {
2580 (
const char *)keyword.
s);
2581 goto error_free_value_bin;
2583 memcpy(&(((
char *)oscore_conf)[oscore_config[i].offset]),
2585 sizeof(value.u.value_bin));
2587 case COAP_ENC_INTEGER:
2589 memcpy(&(((
char *)oscore_conf)[oscore_config[i].offset]),
2591 sizeof(value.u.value_int));
2594 for (j = 0; oscore_config[i].text_mapping[j].text.s !=
NULL; j++) {
2596 &oscore_config[i].text_mapping[j].text)) {
2597 memcpy(&(((
char *)oscore_conf)[oscore_config[i].offset]),
2598 &oscore_config[i].text_mapping[j].value,
2599 sizeof(oscore_config[i].text_mapping[j].value));
2603 if (oscore_config[i].text_mapping[j].text.s ==
NULL) {
2604 coap_log_warn(
"oscore_conf: Keyword '%.*s': value '%.*s' unknown\n",
2606 (
const char *)keyword.
s,
2607 (
int)value.u.value_str.length,
2608 (
const char *)value.u.value_str.s);
2612 case COAP_ENC_UNSIGNED64:
2622 if (i ==
sizeof(oscore_config) /
sizeof(oscore_config[0])) {
2623 coap_log_warn(
"oscore_conf: Keyword '%.*s', type '%s' unknown\n",
2625 (
const char *)keyword.
s,
2626 value.encoding_name);
2627 if (value.encoding == COAP_ENC_HEX || value.encoding == COAP_ENC_ASCII ||
2628 value.encoding == COAP_ENC_CONFIG) {
2636 if (!oscore_conf->master_secret) {
2640 if (!oscore_conf->sender) {
2646error_free_value_bin:
2670 coap_log_crit(
"OSCORE: Could not create Security Context!\n");
2704 if (session ==
NULL || recipient_ctx ==
NULL)
2707 if (session->recipient_ctx == recipient_ctx) {
2712 old_ctx = session->recipient_ctx;
2714 if (old_ctx !=
NULL) {
2721 session->recipient_ctx = recipient_ctx;
2722 session->recipient_ctx->
ref++;
2724 if (old_ctx !=
NULL) {
2734 if (association ==
NULL)
2743 if (recipient_ctx !=
NULL)
2746 if (old_ctx !=
NULL)
2753 void *save_seq_num_func_param,
2754 uint64_t start_seq_num) {
2757 if (oscore_conf ==
NULL)
2772 size_t overhead = 0;
2778 if (osc_ctx ==
NULL)
2835 if (context->p_osc_ctx ==
NULL) {
2840 if (rcp_conf ==
NULL) {
2848 if (rcp_ctx ==
NULL)
2858 if (!context || !recipient_id)
2870 if (context->p_osc_ctx ==
NULL)
2879 if (context ==
NULL)
2883 context->oscore_find_cb = find_handler;
2884 context->oscore_update_seq_num_cb = update_seq_num_handler;
2906 uint64_t last_seq, uint64_t seq_window) {
2919 uint64_t last_seq, uint64_t seq_window) {
2922 rcp_conf = coap_oscore_get_recipient_conf(oscore_conf, recipient_id);
3060 void *save_seq_num_func_param,
3061 uint64_t start_seq_num) {
3063 (void)save_seq_num_func;
3064 (void)save_seq_num_func_param;
3065 (void)start_seq_num;
3097 (void)update_seq_num_handler;
3103 uint64_t last_seq, uint64_t seq_window) {
struct coap_lg_crcv_t coap_lg_crcv_t
Library specific build wrapper for coap_internal.h.
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.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
uint8_t coap_opt_t
Use byte-oriented access methods here because sliding a complex struct coap_opt_t over the data buffe...
@ COAP_OPTION_IF_NONE_MATCH
@ COAP_OPTION_PROXY_SCHEME
@ COAP_OPTION_CONTENT_FORMAT
@ COAP_OPTION_LOCATION_QUERY
@ COAP_OPTION_LOCATION_PATH
@ COAP_OPTION_URI_PATH_ABB
static int coap_uri_scheme_is_secure(const coap_uri_t *uri)
coap_mid_t coap_send_ack_lkd(coap_session_t *session, const coap_pdu_t *request)
Sends an ACK message with code 0 for the specified request to dst.
int coap_prng_lkd(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
int coap_handle_event_lkd(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
coap_mid_t coap_send_internal(coap_session_t *session, coap_pdu_t *pdu, coap_pdu_t *request_pdu)
Sends a CoAP message to given peer.
void coap_cancel_all_messages(coap_context_t *context, coap_session_t *session, coap_bin_const_t *token)
Cancels all outstanding messages for session session that have the specified token.
#define COAP_OSCORE_DEFAULT_REPLAY_WINDOW
int coap_crypto_check_hkdf_alg(cose_hkdf_alg_t hkdf_alg)
Check whether the defined hkdf algorithm is supported by the underlying crypto library.
int coap_crypto_check_cipher_alg(cose_alg_t alg)
Check whether the defined cipher algorithm is supported by the underlying crypto library.
unsigned int coap_encode_var_safe(uint8_t *buf, size_t length, unsigned int val)
Encodes multiple-length byte sequences.
unsigned int coap_decode_var_bytes(const uint8_t *buf, size_t len)
Decodes multiple-length byte sequences.
uint64_t coap_decode_var_bytes8(const uint8_t *buf, size_t len)
Decodes multiple-length byte sequences.
unsigned int coap_encode_var_safe8(uint8_t *buf, size_t length, uint64_t val)
Encodes multiple-length byte sequences.
@ COAP_EVENT_OSCORE_DECODE_ERROR
Triggered when there is an OSCORE decode of OSCORE option failure.
@ COAP_EVENT_OSCORE_INTERNAL_ERROR
Triggered when there is an OSCORE internal error i.e malloc failed.
@ COAP_EVENT_OSCORE_NOT_ENABLED
Triggered when trying to use OSCORE to decrypt, but it is not enabled.
@ COAP_EVENT_OSCORE_RECIPIENT_CHANGED
Triggered when coap_oscore_session_set_recipient_ctx() replaces the recipient context bound to a sess...
@ COAP_EVENT_OSCORE_NO_SECURITY
Triggered when there is no OSCORE security definition found.
@ COAP_EVENT_OSCORE_NO_PROTECTED_PAYLOAD
Triggered when there is no OSCORE encrypted payload provided.
@ COAP_EVENT_OSCORE_DECRYPTION_FAILURE
Triggered when there is an OSCORE decryption failure.
#define coap_lock_callback(func)
Dummy for no thread-safe code.
#define coap_lock_unlock()
Dummy for no thread-safe code.
#define coap_lock_check_locked()
Dummy for no thread-safe code.
#define coap_lock_lock(failed)
Dummy for no thread-safe code.
#define coap_log_debug(...)
coap_log_t coap_get_log_level(void)
Get the current logging level.
void coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu)
Display the contents of the specified pdu.
#define coap_log_oscore(...)
#define coap_log_warn(...)
#define coap_log_err(...)
#define coap_log_crit(...)
coap_opt_t * coap_option_next(coap_opt_iterator_t *oi)
Updates the iterator oi to point to the next option.
uint32_t coap_opt_length(const coap_opt_t *opt)
Returns the length of the given option.
coap_opt_iterator_t * coap_option_iterator_init(const coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t *filter)
Initializes the given option iterator oi to point to the beginning of the pdu's option list.
void coap_delete_optlist(coap_optlist_t *queue)
Removes all entries from the optlist_chain, freeing off their memory usage.
#define COAP_OPT_ALL
Pre-defined filter that includes all options.
int coap_add_optlist_pdu(coap_pdu_t *pdu, coap_optlist_t **options)
The current optlist of optlist_chain is first sorted (as per RFC7272 ordering requirements) and then ...
coap_opt_t * coap_check_option(const coap_pdu_t *pdu, coap_option_num_t number, coap_opt_iterator_t *oi)
Retrieves the first option of number number from pdu.
const uint8_t * coap_opt_value(const coap_opt_t *opt)
Returns a pointer to the value of the given option.
uint64_t oscore_cbor_get_element_size(const uint8_t **buffer, size_t *buf_size)
void cose_encrypt0_set_plaintext(cose_encrypt0_t *ptr, uint8_t *buffer, size_t size)
int cose_encrypt0_set_key(cose_encrypt0_t *ptr, coap_bin_const_t *key)
void cose_encrypt0_set_kid_context(cose_encrypt0_t *ptr, coap_bin_const_t *kid_context)
const char * cose_get_alg_name(cose_alg_t id, char *buffer, size_t buflen)
void cose_encrypt0_set_ciphertext(cose_encrypt0_t *ptr, uint8_t *buffer, size_t size)
int cose_encrypt0_decrypt(cose_encrypt0_t *ptr, uint8_t *plaintext_buffer, size_t plaintext_len)
size_t cose_tag_len(cose_alg_t cose_alg)
void cose_encrypt0_set_aad(cose_encrypt0_t *ptr, coap_bin_const_t *aad)
int cose_encrypt0_encrypt(cose_encrypt0_t *ptr, uint8_t *ciphertext_buffer, size_t ciphertext_len)
void cose_encrypt0_set_partial_iv(cose_encrypt0_t *ptr, coap_bin_const_t *partial_iv)
void cose_encrypt0_set_external_aad(cose_encrypt0_t *ptr, coap_bin_const_t *external_aad)
void cose_encrypt0_init(cose_encrypt0_t *ptr)
void cose_encrypt0_set_alg(cose_encrypt0_t *ptr, uint8_t alg)
void cose_encrypt0_set_key_id(cose_encrypt0_t *ptr, coap_bin_const_t *key_id)
void cose_encrypt0_set_nonce(cose_encrypt0_t *ptr, coap_bin_const_t *nonce)
@ COSE_HKDF_ALG_HKDF_SHA_256
@ COSE_ALGORITHM_AES_CCM_16_64_128
@ COSE_ALGORITHM_AES_CCM_16_64_256
size_t oscore_prepare_aad(const uint8_t *external_aad_buffer, size_t external_aad_len, uint8_t *aad_buffer, size_t aad_size)
void oscore_reference_recipient_ctx(oscore_recipient_ctx_t *recipient_ctx)
Increment the recipient context reference count.
void coap_oscore_association_set_recipient_ctx(oscore_association_t *association, oscore_recipient_ctx_t *recipient_ctx)
Set the recipient context of an association.
oscore_ctx_t * oscore_derive_ctx_from_conf(coap_oscore_conf_t *oscore_conf)
oscore_derive_ctx_from_conf - derive a osc_ctx from oscore_conf information
int coap_delete_oscore_recipient_lkd(coap_context_t *context, coap_bin_const_t *recipient_id)
Release all the information associated for the specific Recipient ID (and hence and stop any further ...
int oscore_delete_association(coap_session_t *session, oscore_association_t *association)
coap_session_t * coap_new_client_session_oscore3_lkd(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_oscore_conf_t *oscore_conf, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, protecting the data using OSCORE,...
uint8_t oscore_validate_sender_seq(oscore_recipient_ctx_t *ctx, cose_encrypt0_t *cose)
oscore_recipient_ctx_t * oscore_add_recipient(oscore_ctx_t *ctx, coap_oscore_rcp_conf_t *rcp_conf, uint32_t break_key)
oscore_add_recipient - add in recipient information
oscore_ctx_t * coap_init_oscore_context_from_conf(coap_oscore_conf_t *oscore_conf)
Initializes an OSCORE context from the given configuration.
void coap_oscore_session_set_recipient_ctx(coap_session_t *session, oscore_recipient_ctx_t *recipient_ctx)
Attach the OSCORE recipient context information to the session.
int oscore_decode_option_value(const uint8_t *option_value, size_t option_len, cose_encrypt0_t *cose)
int coap_delete_oscore_snd_conf(coap_oscore_snd_conf_t *oscore_snd_conf)
Release all the information associated with the OSCORE complex Sender configuration.
coap_pdu_t * coap_oscore_new_pdu_encrypted_lkd(coap_session_t *session, coap_pdu_t *pdu, coap_bin_const_t *kid_context, oscore_partial_iv_t send_partial_iv)
Encrypts the specified pdu when OSCORE encryption is required on session.
int oscore_delete_recipient(oscore_ctx_t *osc_ctx, coap_bin_const_t *rid)
uint8_t oscore_increment_sender_seq(oscore_ctx_t *ctx)
void oscore_update_ctx(oscore_ctx_t *osc_ctx, coap_bin_const_t *id_context)
oscore_update_ctx - update a osc_ctx with a new id_context
coap_session_t * coap_new_client_session_oscore_psk3_lkd(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_cpsk_t *psk_data, coap_oscore_conf_t *oscore_conf, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, with PSK credentials protecting the data using...
oscore_ctx_t * oscore_derive_ctx(coap_context_t *c_context, coap_oscore_conf_t *oscore_conf)
oscore_derive_ctx - derive a osc_ctx from oscore_conf information
COAP_API coap_pdu_t * coap_oscore_new_pdu_encrypted(coap_session_t *session, coap_pdu_t *pdu, coap_bin_const_t *kid_context, oscore_partial_iv_t send_partial_iv)
Encrypts the specified pdu when OSCORE encryption is required on session.
void oscore_roll_back_seq(oscore_recipient_ctx_t *ctx)
int oscore_new_association(coap_session_t *session, coap_pdu_t *sent_pdu, coap_bin_const_t *token, oscore_recipient_ctx_t *recipient_ctx, coap_bin_const_t *aad, coap_bin_const_t *nonce, coap_bin_const_t *partial_iv, int is_observe)
size_t oscore_prepare_e_aad(oscore_ctx_t *ctx, cose_encrypt0_t *cose, const uint8_t *oscore_option, size_t oscore_option_len, coap_bin_const_t *sender_public_key, uint8_t *external_aad_ptr, size_t external_aad_size)
void oscore_delete_server_associations(coap_session_t *session)
void oscore_log_char_value(coap_log_t level, const char *name, const char *value)
oscore_ctx_t * oscore_find_context(coap_session_t *session, const coap_bin_const_t rcpkey_id, const coap_bin_const_t *ctxkey_id, uint8_t *oscore_r2, oscore_recipient_ctx_t **recipient_ctx)
oscore_find_context - Locate recipient context (and hence OSCORE context)
struct coap_pdu_t * coap_oscore_decrypt_pdu(coap_session_t *session, coap_pdu_t *pdu)
Decrypts the OSCORE-encrypted parts of pdu when OSCORE is used.
int coap_oscore_recipient_set_latest_seq_lkd(coap_oscore_conf_t *oscore_conf, const coap_bin_const_t *recipient_id, uint64_t last_seq, uint64_t seq_window)
Set the latest sequence number and sliding window for the specified recipient id in the compiled conf...
int coap_rebuild_pdu_for_proxy(coap_pdu_t *pdu)
Convert PDU to use Proxy-Scheme option if Proxy-Uri option is present.
void oscore_free_contexts(coap_context_t *c_context)
void oscore_log_hex_value(coap_log_t level, const char *name, coap_bin_const_t *value)
void coap_delete_oscore_associations(coap_session_t *session)
Cleanup all allocated OSCORE association information.
int coap_oscore_initiate(coap_session_t *session, coap_oscore_conf_t *oscore_conf)
Initiate an OSCORE session.
int coap_new_oscore_recipient_lkd(coap_context_t *context, coap_bin_const_t *recipient_id)
Add in the specific Recipient ID into the OSCORE context (server only).
oscore_ctx_t * oscore_duplicate_ctx(coap_context_t *c_context, oscore_ctx_t *o_osc_ctx, coap_bin_const_t *sender_id, coap_bin_const_t *recipient_id, coap_bin_const_t *id_context)
oscore_duplicate_ctx - duplicate a osc_ctx
void coap_delete_all_oscore(coap_context_t *context)
Cleanup all allocated OSCORE information.
void oscore_generate_nonce(cose_encrypt0_t *ptr, oscore_ctx_t *ctx, uint8_t *buffer, uint8_t size)
int oscore_remove_context(coap_context_t *c_context, oscore_ctx_t *osc_ctx)
oscore_association_t * oscore_find_association(coap_session_t *session, coap_bin_const_t *token)
int coap_context_oscore_server_lkd(coap_context_t *context, coap_oscore_conf_t *oscore_conf)
Set the context's default OSCORE configuration for a server.
int coap_delete_oscore_rcp_conf(coap_oscore_rcp_conf_t *oscore_rcp_conf)
Release all the information associated with the OSCORE complex Recipient configuration.
void oscore_release_recipient_ctx(oscore_recipient_ctx_t **recipient_ctx)
Cleanup recipient context, including releasing the oscore context if the oscore context referenced is...
coap_session_t * coap_new_client_session_oscore_pki3_lkd(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_pki_t *pki_data, coap_oscore_conf_t *oscore_conf, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, with PKI credentials protecting the data using...
ssize_t oscore_encode_option_value(uint8_t *option_buffer, size_t option_buf_len, cose_encrypt0_t *cose, uint8_t group_flag, uint8_t appendix_b_2)
Encode the OSCORE option.
size_t coap_oscore_overhead(coap_session_t *session, coap_pdu_t *pdu)
Determine the additional data size requirements for adding in OSCORE.
@ OSCORE_SEND_PARTIAL_IV
Send partial IV with encrypted PDU.
@ OSCORE_SEND_NO_IV
Do not send partial IV unless added by a response.
COAP_API int coap_oscore_recipient_set_latest_seq(coap_oscore_conf_t *oscore_conf, const coap_bin_const_t *recipient_id, uint64_t last_seq, uint64_t seq_window)
Set the latest sequence number and sliding window for the specified recipient id in the compiled conf...
coap_oscore_conf_t * coap_new_oscore_conf(coap_str_const_t conf_mem, coap_oscore_save_seq_num_t save_seq_num_func, void *save_seq_num_func_param, uint64_t start_seq_num)
Parse an OSCORE configuration (held in memory) and populate a OSCORE configuration structure.
coap_session_t * coap_new_client_session_oscore_psk(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_cpsk_t *psk_data, coap_oscore_conf_t *oscore_conf)
Creates a new client session to the designated server with PSK credentials as well as protecting the ...
coap_session_t * coap_new_client_session_oscore_psk3(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_cpsk_t *psk_data, coap_oscore_conf_t *oscore_conf, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, with PSK credentials protecting the data using...
int(* coap_oscore_update_seq_num_handler_t)(const coap_session_t *session, const coap_bin_const_t *rcpkey_id, const coap_bin_const_t *ctxkey_id, uint64_t receiver_seq_num, uint64_t seq_num_window)
Callback function type for persisting the OSCORE receiver sequence number and anti-replay sliding win...
int coap_delete_oscore_conf(coap_oscore_conf_t *oscore_conf)
Release all the information associated with the OSCORE configuration.
coap_session_t * coap_new_client_session_oscore(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_oscore_conf_t *oscore_conf)
Creates a new client session to the designated server, protecting the data using OSCORE.
int coap_context_oscore_server(coap_context_t *context, coap_oscore_conf_t *oscore_conf)
Set the context's default OSCORE configuration for a server.
coap_oscore_conf_t *(* coap_oscore_find_handler_t)(const coap_session_t *session, const coap_bin_const_t *rcpkey_id, const coap_bin_const_t *ctxkey_id)
Callback function type for overriding oscore_find_context().
coap_session_t * coap_new_client_session_oscore_pki(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_pki_t *pki_data, coap_oscore_conf_t *oscore_conf)
Creates a new client session to the designated server with PKI credentials as well as protecting the ...
coap_session_t * coap_new_client_session_oscore3(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_oscore_conf_t *oscore_conf, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, protecting the data using OSCORE,...
int coap_new_oscore_recipient(coap_context_t *context, coap_bin_const_t *recipient_id)
Add in the specific Recipient ID into the OSCORE context (server only).
int(* coap_oscore_save_seq_num_t)(uint64_t sender_seq_num, void *param)
Definition of the function used to save the current Sender Sequence Number.
int coap_delete_oscore_recipient(coap_context_t *context, coap_bin_const_t *recipient_id)
Release all the information associated for the specific Recipient ID (and hence stop any further OSCO...
void coap_oscore_register_external_handlers(coap_context_t *context, coap_oscore_find_handler_t find_handler, coap_oscore_update_seq_num_handler_t update_seq_num_handler)
Register external storage handlers for OSCORE session state.
coap_session_t * coap_new_client_session_oscore_pki3(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_pki_t *pki_data, coap_oscore_conf_t *oscore_conf, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, with PKI credentials protecting the data using...
void coap_delete_pdu_lkd(coap_pdu_t *pdu)
Dispose of an CoAP PDU and free off associated storage.
size_t coap_insert_option(coap_pdu_t *pdu, coap_option_num_t number, size_t len, const uint8_t *data)
Inserts option of given number in the pdu with the appropriate data.
int coap_remove_option(coap_pdu_t *pdu, coap_option_num_t number)
Removes (first) option of given number from the pdu.
int coap_update_token(coap_pdu_t *pdu, size_t len, const uint8_t *data)
Updates token in pdu with length len and data.
#define COAP_PDU_IS_PING(pdu)
coap_pdu_t * coap_pdu_duplicate_lkd(const coap_pdu_t *old_pdu, coap_session_t *session, size_t token_length, const uint8_t *token, coap_opt_filter_t *drop_options, coap_bool_t expand_opt_abb)
Duplicate an existing PDU.
size_t coap_pdu_encode_header(coap_pdu_t *pdu, coap_proto_t proto)
Compose the protocol specific header for the specified PDU.
#define COAP_PAYLOAD_START
int coap_pdu_resize(coap_pdu_t *pdu, size_t new_size)
Dynamically grows the size of pdu to new_size.
#define COAP_PDU_IS_REQUEST(pdu)
size_t coap_add_option_internal(coap_pdu_t *pdu, coap_option_num_t number, size_t len, const uint8_t *data)
Adds option of given number to pdu that is passed as first parameter.
#define COAP_DEFAULT_PORT
#define COAP_RESPONSE_CODE(N)
#define COAP_RESPONSE_CLASS(C)
coap_proto_t
CoAP protocol types Note: coap_layers_coap[] needs updating if extended.
coap_pdu_code_t
Set of codes available for a PDU.
int coap_add_token(coap_pdu_t *pdu, size_t len, const uint8_t *data)
Adds token of length len to pdu.
#define COAPS_DEFAULT_PORT
int coap_get_data(const coap_pdu_t *pdu, size_t *len, const uint8_t **data)
Retrieves the length and data pointer of specified PDU.
coap_pdu_t * coap_pdu_init(coap_pdu_type_t type, coap_pdu_code_t code, coap_mid_t mid, size_t size)
Creates a new CoAP PDU with at least enough storage space for the given size maximum message size.
#define COAP_INVALID_MID
Indicates an invalid message id.
int coap_add_data(coap_pdu_t *pdu, size_t len, const uint8_t *data)
Adds given data to the pdu that is passed as first parameter.
coap_bin_const_t coap_pdu_get_token(const coap_pdu_t *pdu)
Gets the token associated with pdu.
@ COAP_REQUEST_CODE_FETCH
coap_session_t * coap_new_client_session_pki3_lkd(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_pki_t *setup_data, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, with PKI credentials along with app_data infor...
coap_session_t * coap_new_client_session_psk3_lkd(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_cpsk_t *setup_data, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, with PSK credentials along with app_data infor...
void coap_session_release_lkd(coap_session_t *session)
Decrement reference counter on a session.
coap_session_t * coap_new_client_session3_lkd(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, void *app_data, coap_app_data_free_callback_t callback, coap_str_const_t *ws_host)
Creates a new client session to the designated server, with PSK credentials along with app_data infor...
void(* coap_app_data_free_callback_t)(void *data)
Callback to free off the app data when the entry is being deleted / freed off.
void coap_delete_bin_const(coap_bin_const_t *s)
Deletes the given const binary data and releases any memory allocated.
void coap_delete_str_const(coap_str_const_t *s)
Deletes the given const string and releases any memory allocated.
coap_binary_t * coap_new_binary(size_t size)
Returns a new binary object with at least size bytes storage allocated.
coap_str_const_t * coap_make_str_const(const char *string)
Take the specified byte array (text) and create a coap_str_const_t *.
coap_bin_const_t * coap_new_bin_const(const uint8_t *data, size_t size)
Take the specified byte array (text) and create a coap_bin_const_t * Returns a new const binary objec...
struct coap_str_const_t coap_str_const_t
CoAP string data definition with const data.
void coap_delete_binary(coap_binary_t *s)
Deletes the given coap_binary_t object and releases any memory allocated.
#define coap_binary_equal(binary1, binary2)
Compares the two binary data for equality.
#define coap_string_equal(string1, string2)
Compares the two strings for equality.
coap_str_const_t * coap_new_str_const(const uint8_t *data, size_t size)
Returns a new const string object with at least size+1 bytes storage allocated, and the provided data...
int coap_oscore_is_supported(void)
Check whether OSCORE is available.
int coap_query_into_optlist(const uint8_t *s, size_t length, coap_option_num_t optnum, coap_optlist_t **optlist_chain)
Splits the given URI query into '&' separate segments, and then adds the Uri-Query / Location-Query o...
int coap_path_into_optlist(const uint8_t *s, size_t length, coap_option_num_t optnum, coap_optlist_t **optlist_chain)
Splits the given URI path into '/' separate segments, and then adds the Uri-Path / Location-Path opti...
int coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri)
Parses a given string into URI components.
coap_uri_info_t coap_uri_scheme[COAP_URI_SCHEME_LAST]
Multi-purpose address abstraction.
CoAP binary data definition with const data.
size_t length
length of binary data
const uint8_t * s
read-only binary data
CoAP binary data definition.
size_t length
length of binary data
The CoAP stack's global state is stored in a coap_context_t object.
The structure used for defining the Client PSK setup data to be used.
The structure used for defining the PKI setup data to be used.
Iterator to run through PDU options.
coap_opt_t * next_option
pointer to the unparsed next option
size_t length
remaining length of PDU
coap_option_num_t number
decoded option number
Representation of chained list of CoAP options to install.
The structure used to hold the OSCORE configuration information.
void * save_seq_num_func_param
Passed to save_seq_num_func().
uint32_t rfc8613_b_2
1 if rfc8613 B.2 protocol else 0
cose_hkdf_alg_t hkdf_alg
Set to one of COSE_HKDF_ALG_*.
uint32_t break_sender_key
1 if sender key to be broken, else 0
coap_oscore_snd_conf_t * sender
The sender - i.e.
coap_oscore_rcp_conf_t * recipient_chain
The recipients as a chain.
uint32_t ssn_freq
Sender Seq Num update frequency.
coap_oscore_save_seq_num_t save_seq_num_func
Called every seq num change.
uint32_t rfc8613_b_1_2
1 if rfc8613 B.1.2 enabled else 0
uint64_t start_seq_num
Used for ssn_freq updating.
uint32_t break_recipient_key
1 if recipient key to be broken, else 0
coap_bin_const_t * master_secret
Common Master Secret.
cose_alg_t aead_alg
Set to one of COSE_ALGORITHM_AES*.
coap_bin_const_t * master_salt
Common Master Salt.
uint32_t replay_window
Replay window size Use COAP_OSCORE_DEFAULT_REPLAY_WINDOW.
coap_bin_const_t * id_context
Common ID context.
The structure used to hold the OSCORE Recipient configuration.
coap_bin_const_t * recipient_id
Recipient ID (i.e.
uint64_t last_seq
Highest sequence number used for this recipient.
uint8_t window_initialized
Contains if the sliding window is initialized 1 if initialized, 0 otherwise.
struct coap_oscore_rcp_conf_t * next_recipient
Used to maintain the chain.
uint64_t sliding_window
bitfield sequence counter window
The structure used to hold the OSCORE Sender configuration information.
coap_bin_const_t * sender_id
Sender ID (i.e.
uint8_t max_hdr_size
space reserved for protocol-specific header
uint8_t * token
first byte of token (or extended length bytes prefix), if any, or options
coap_pdu_code_t code
request method (value 1–31) or response code (value 64-255)
coap_bin_const_t actual_token
Actual token in pdu.
uint8_t * data
first byte of payload, if any
coap_mid_t mid
message id, if any, in regular host byte order
uint32_t e_token_length
length of Token space (includes leading extended bytes
size_t used_size
used bytes of storage for token, options and payload
coap_pdu_type_t type
message type
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
uint32_t max_token_size
Largest token size supported RFC8974.
coap_proto_t proto
protocol used
unsigned ref
reference count from queues
uint8_t con_active
Active CON request sent.
coap_context_t * context
session's context
CoAP string data definition with const data.
const uint8_t * s
read-only string data
size_t length
length of string
Representation of parsed URI.
enum coap_uri_scheme_t scheme
The parsed scheme specifier.
coap_str_const_t path
The complete path if present or {0, NULL}.
uint16_t port
The port in host byte order.
coap_str_const_t query
The complete query if present or {0, NULL}.
coap_str_const_t host
The host part of the URI.
coap_bin_const_t partial_iv
coap_bin_const_t kid_context
coap_bin_const_t external_aad
coap_bin_const_t oscore_option
coap_bin_const_t * obs_partial_iv
coap_bin_const_t * partial_iv
oscore_recipient_ctx_t * recipient_ctx
uint8_t rfc8613_b_1_2
1 if rfc8613 B.1.2 enabled else 0
void * save_seq_num_func_param
Passed to save_seq_num_func().
oscore_sender_ctx_t * sender_context
cose_alg_t aead_alg
Set to one of COSE_ALGORITHM_AES*.
uint8_t rfc8613_b_2
1 if rfc8613 B.2 protocol else 0
coap_oscore_save_seq_num_t save_seq_num_func
Called every seq num change.
oscore_recipient_ctx_t * recipient_chain
coap_bin_const_t * id_context
contains GID in case of group
uint32_t ssn_freq
Sender Seq Num update frequency.
coap_bin_const_t * recipient_key
coap_bin_const_t * recipient_id
coap_bin_const_t * sender_id
uint64_t seq
Sender Sequence Number.
coap_bin_const_t * sender_key
uint64_t next_seq
Used for ssn_freq updating.