20#ifdef COAP_WITH_LIBTINYDTLS
23#undef PACKAGE_BUGREPORT
31#include <tinydtls/tinydtls.h>
32#include <tinydtls/dtls.h>
33#include <tinydtls/dtls_debug.h>
34#include <tinydtls/dtls_time.h>
38#include <dtls_debug.h>
42typedef struct coap_tiny_context_t {
43 struct dtls_context_t *dtls_context;
52#if ! defined(DTLS_PSK) && ! defined(DTLS_ECC)
53#error Neither DTLS_PSK or DTLS_ECC defined
56static dtls_tick_t dtls_tick_0 = 0;
109dtls_map_logging(log_t d_level) {
124 case DTLS_LOG_NOTICE:
137#ifdef HAVE_DTLS_SET_LOG_HANDLER
140dtls_logging(log_t d_level,
const char *message) {
141 coap_log_t c_level = dtls_map_logging(d_level);
150 dtls_ticks(&dtls_tick_0);
152#ifdef HAVE_DTLS_SET_LOG_HANDLER
154 dtls_set_log_handler(dtls_logging);
168 const coap_tiny_context_t *t_context =
171 return t_context->dtls_context;
183 d_level = DTLS_LOG_EMERG;
186 d_level = DTLS_LOG_ALERT;
190 d_level = DTLS_LOG_CRIT;
193 d_level = DTLS_LOG_WARN;
196 d_level = DTLS_LOG_NOTICE;
199 d_level = DTLS_LOG_INFO;
205 d_level = DTLS_LOG_DEBUG;
208 dtls_set_log_level(d_level);
213 log_t d_level = dtls_get_log_level();
215 return dtls_map_logging(d_level);
220#if defined(WITH_CONTIKI) || defined(WITH_LWIP)
223#elif defined(WITH_RIOT_SOCK)
224 if (s->addr.family == AF_INET6) {
226 a->
addr.
sa.sa_family = s->addr.family;
227 memcpy(&a->
addr.
sin6.sin6_addr, &s->addr.ipv6,
229 a->
addr.
sin6.sin6_port = s->addr.port;
231 }
else if (s->addr.family == AF_INET) {
232 a->
addr.
sa.sa_family = s->addr.family;
234 memcpy(&a->
addr.
sin.sin_addr, &s->addr.ipv4,
sizeof(a->
addr.
sin.sin_addr));
235 a->
addr.
sin.sin_port = s->addr.port;
239 if (s->addr.sa.sa_family == AF_INET6) {
242 }
else if (s->addr.sa.sa_family == AF_INET) {
246 a->
size = (socklen_t)s->size;
254#if defined(WITH_CONTIKI) || defined(WITH_LWIP)
255 s->size = (
unsigned char)
sizeof(s->addr);
258#elif defined(WITH_RIOT_SOCK)
259 if (a->
addr.
sa.sa_family == AF_INET6) {
260 s->
size = (socklen_t)
sizeof(s->addr.ipv6);
261 s->addr.family = a->
addr.
sa.sa_family;
262 memcpy(&s->addr.ipv6, &a->
addr.
sin6.sin6_addr,
263 sizeof(s->addr.ipv6));
264 s->addr.port = a->
addr.
sin6.sin6_port;
266 }
else if (a->
addr.
sa.sa_family == AF_INET) {
267 s->size = (socklen_t)
sizeof(s->addr.ipv4);
268 s->addr.family = a->
addr.
sa.sa_family;
270 s->addr.port = a->
addr.
sin.sin_port;
274 if (a->
addr.
sa.sa_family == AF_INET6) {
275 s->size = (socklen_t)
sizeof(s->addr.sin6);
277 }
else if (a->
addr.
sa.sa_family == AF_INET) {
278 s->size = (socklen_t)
sizeof(s->addr.sin);
281 s->size = (socklen_t)a->
size;
288dtls_send_to_peer(
struct dtls_context_t *dtls_context,
289 session_t *dtls_session, uint8 *data,
size_t len) {
290 coap_tiny_context_t *t_context =
291 (coap_tiny_context_t *)dtls_get_app_data(dtls_context);
292 coap_context_t *coap_context = t_context ? t_context->coap_context : NULL;
296 assert(coap_context);
297 get_session_addr(dtls_session, &remote_addr);
300 coap_log_warn(
"dtls_send_to_peer: cannot find local interface\n");
308dtls_application_data(
struct dtls_context_t *dtls_context,
309 session_t *dtls_session, uint8 *data,
size_t len) {
310 coap_tiny_context_t *t_context =
311 (coap_tiny_context_t *)dtls_get_app_data(dtls_context);
312 coap_context_t *coap_context = t_context ? t_context->coap_context : NULL;
316 assert(coap_context);
317 get_session_addr(dtls_session, &remote_addr);
320 coap_log_debug(
"dropped message that was received on invalid interface\n");
327static int coap_event_dtls = 0;
330dtls_event(
struct dtls_context_t *dtls_context,
331 session_t *dtls_session,
332 dtls_alert_level_t level,
337 if (level == DTLS_ALERT_LEVEL_FATAL)
342 case DTLS_ALERT_CLOSE_NOTIFY: {
346 case DTLS_EVENT_CONNECTED: {
350#ifdef DTLS_EVENT_RENEGOTIATE
351 case DTLS_EVENT_RENEGOTIATE: {
368get_psk_info(
struct dtls_context_t *dtls_context,
369 const session_t *dtls_session,
370 dtls_credentials_type_t type,
371 const uint8_t *
id,
size_t id_len,
372 unsigned char *result,
size_t result_length) {
374 coap_tiny_context_t *t_context =
375 (coap_tiny_context_t *)dtls_get_app_data(dtls_context);
376 coap_context_t *coap_context = t_context ? t_context->coap_context : NULL;
378 int fatal_error = DTLS_ALERT_INTERNAL_ERROR;
380#if COAP_CLIENT_SUPPORT
386#if COAP_SERVER_SUPPORT
391 assert(coap_context);
392 get_session_addr(dtls_session, &remote_addr);
400 case DTLS_PSK_IDENTITY:
402#if COAP_CLIENT_SUPPORT
414 id ? (
const char *)
id :
"");
426 psk_identity = &cpsk_info->
identity;
435 if (psk_identity == NULL) {
437 fatal_error = DTLS_ALERT_CLOSE_NOTIFY;
440 if (psk_identity->
length > result_length) {
441 coap_log_warn(
"psk_identity too large, truncated to %zd bytes\n",
445 result_length = psk_identity->
length;
447 memcpy(result, psk_identity->
s, result_length);
448 return result_length;
454#if COAP_CLIENT_SUPPORT
457 if (psk_key == NULL) {
459 fatal_error = DTLS_ALERT_CLOSE_NOTIFY;
462 if (psk_key->
length > result_length) {
467 result_length = psk_key->
length;
469 memcpy(result, psk_key->
s, result_length);
470 return result_length;
473#if COAP_SERVER_SUPPORT
477 lidentity.
length =
id ? id_len : 0;
478 lidentity.
s =
id ? (
const uint8_t *)
id : (
const uint8_t *)
"";
485 (
int)lidentity.
length, lidentity.
s);
496 if (psk_key == NULL) {
502 if (psk_key->
length > result_length) {
507 result_length = psk_key->
length;
509 memcpy(result, psk_key->
s, result_length);
510 return result_length;
516#if COAP_SERVER_SUPPORT
518 if (psk_hint == NULL)
520 if (psk_hint->
length > result_length) {
521 coap_log_warn(
"psk_hint too large, truncated to %zd bytes\n",
525 result_length = psk_hint->
length;
527 memcpy(result, psk_hint->
s, result_length);
528 return result_length;
538 return dtls_alert_fatal_create(fatal_error);
544get_ecdsa_key(
struct dtls_context_t *dtls_context,
546 const dtls_ecdsa_key_t **result) {
547 static dtls_ecdsa_key_t ecdsa_key;
548 coap_tiny_context_t *t_context =
549 (coap_tiny_context_t *)dtls_get_app_data(dtls_context);
551 ecdsa_key.curve = DTLS_ECDH_CURVE_SECP256R1;
552 ecdsa_key.priv_key = t_context->priv_key->s;
553 ecdsa_key.pub_key_x = t_context->pub_key->s;
554 ecdsa_key.pub_key_y = &t_context->pub_key->s[DTLS_EC_KEY_SIZE];
556 *result = &ecdsa_key;
561static const unsigned char cert_asn1_header[] = {
565 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01,
567 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07,
571#define DTLS_CE_LENGTH (sizeof(cert_asn1_header) + key_size + key_size)
574verify_ecdsa_key(
struct dtls_context_t *dtls_context
COAP_UNUSED,
576 const uint8_t *other_pub_x,
577 const uint8_t *other_pub_y,
579 coap_tiny_context_t *t_context =
580 (coap_tiny_context_t *)dtls_get_app_data(dtls_context);
581 if (t_context && t_context->setup_data.validate_cn_call_back) {
584 uint8 buf[DTLS_CE_LENGTH];
593 memcpy(p, &cert_asn1_header,
sizeof(cert_asn1_header));
594 p +=
sizeof(cert_asn1_header);
596 memcpy(p, other_pub_x, key_size);
599 memcpy(p, other_pub_y, key_size);
602 assert(p <= (buf +
sizeof(buf)));
604 get_session_addr(dtls_session, &remote_addr);
606 &remote_addr, dtls_session->ifindex);
610 buf, p-buf, c_session, 0, 1, t_context->setup_data.cn_call_back_arg)) {
616static dtls_handler_t ec_cb = {
617 .write = dtls_send_to_peer,
618 .read = dtls_application_data,
621 .get_psk_info = NULL,
623 .get_ecdsa_key = get_ecdsa_key,
624 .verify_ecdsa_key = verify_ecdsa_key
628static dtls_handler_t psk_cb = {
629 .write = dtls_send_to_peer,
630 .read = dtls_application_data,
633 .get_psk_info = get_psk_info,
636 .get_ecdsa_key = NULL,
637 .verify_ecdsa_key = NULL
644 struct dtls_context_t *dtls_context = t_context ? dtls_new_context(t_context) : NULL;
647 memset(t_context, 0,
sizeof(coap_tiny_context_t));
648 t_context->coap_context = coap_context;
650 dtls_set_handler(dtls_context, &psk_cb);
663 coap_tiny_context_t *t_context = (coap_tiny_context_t *)handle;
665 if (t_context->priv_key) {
667 t_context->priv_key = NULL;
669 if (t_context->pub_key) {
671 t_context->pub_key = NULL;
674 if (t_context->dtls_context)
675 dtls_free_context(t_context->dtls_context);
687 dtls_session_init(dtls_session);
689 dtls_session->ifindex = session->
ifindex;
696#if COAP_SERVER_SUPPORT
699 return coap_dtls_new_session(session);
703#if COAP_CLIENT_SUPPORT
708 dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL;
709 session_t *dtls_session = dtls_context ? coap_dtls_new_session(session) : NULL;
714 dtls_get_peer(dtls_context, dtls_session);
720 if (dtls_connect(dtls_context, dtls_session) >= 0) {
722 dtls_get_peer(dtls_context, dtls_session);
743 coap_tiny_context_t *t_context =
745 dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL;
747 if (dtls_context == NULL)
749 if (coap_session->
tls && dtls_context) {
750 dtls_peer_t *peer = dtls_get_peer(dtls_context, (session_t *)coap_session->
tls);
752 dtls_reset_peer(dtls_context, peer);
754 dtls_close(dtls_context, (session_t *)coap_session->
tls);
757 coap_session->
tls = NULL;
769 dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL;
771 assert(dtls_context);
773 coap_event_dtls = -1;
775 memcpy(&data_rw, &data,
sizeof(data_rw));
776 res = dtls_write(dtls_context,
777 (session_t *)session->
tls, data_rw, data_len);
782 if (coap_event_dtls >= 0) {
793 if (res == (ssize_t)data_len)
810 clock_time_t next = 0;
811 coap_tiny_context_t *t_context = (coap_tiny_context_t *)tiny_context;
812 dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL;
814 dtls_check_retransmit(dtls_context, &next);
843 session_t *dtls_session = (session_t *)session->
tls;
847 dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL;
849 assert(dtls_context);
850 coap_event_dtls = -1;
852 memcpy(&data_rw, &data,
sizeof(data_rw));
853 err = dtls_handle_message(dtls_context, dtls_session, data_rw, (
int)data_len);
859 if (coap_event_dtls >= 0) {
872#if COAP_SERVER_SUPPORT
878 session_t dtls_session;
880 dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL;
883 assert(dtls_context);
884 dtls_session_init(&dtls_session);
886 dtls_session.ifindex = session->
ifindex;
888 memcpy(&data_rw, &data,
sizeof(data_rw));
889 int res = dtls_handle_message(dtls_context, &dtls_session,
890 data_rw, (
int)data_len);
892 if (dtls_get_peer(dtls_context, &dtls_session))
915 const char *vers = dtls_package_version();
919 long int p1, p2 = 0, p3 = 0;
922 p1 = strtol(vers, &endptr, 10);
923 if (*endptr ==
'.') {
924 p2 = strtol(endptr+1, &endptr, 10);
925 if (*endptr ==
'.') {
926 p3 = strtol(endptr+1, &endptr, 10);
929 version.
version = (p1 << 16) | (p2 << 8) | p3;
937static const uint8_t b64_6[256] = {
938 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
939 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
941 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
943 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
945 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
947 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
949 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
951 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
952 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
953 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
954 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
955 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
956 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
957 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
958 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
959 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
964pem_base64_decode(
const uint8_t *data,
size_t size) {
966 size_t nbytesdecoded;
971 size_t nb64bytes = 0;
973 for (i = 0; i < size; i++) {
981 if (b64_6[data[i]] == 64)
983 tbuf[nb64bytes++] = data[i];
989 nbytesdecoded = ((nb64bytes + 3) / 4) * 3;
997 while (nb64bytes > 4) {
998 *(out++) = b64_6[ptr[0]] << 2 | b64_6[ptr[1]] >> 4;
999 *(out++) = b64_6[ptr[1]] << 4 | b64_6[ptr[2]] >> 2;
1000 *(out++) = b64_6[ptr[2]] << 6 | b64_6[ptr[3]];
1006 if (nb64bytes > 1) {
1007 *(out++) = b64_6[ptr[0]] << 2 | b64_6[ptr[1]] >> 4;
1009 if (nb64bytes > 2) {
1010 *(out++) = b64_6[ptr[1]] << 4 | b64_6[ptr[2]] >> 2;
1012 if (nb64bytes > 3) {
1013 *(out++) = b64_6[ptr[2]] << 6 | b64_6[ptr[3]];
1016 decoded->
length = nbytesdecoded - ((4 - nb64bytes) & 3);
1021typedef coap_binary_t *(*asn1_callback)(
const uint8_t *data,
size_t size);
1024asn1_verify_privkey(
const uint8_t *data,
size_t size) {
1027 if (size - 1 == DTLS_EC_KEY_SIZE && *data ==
'\000') {
1033 if (size != DTLS_EC_KEY_SIZE)
1040asn1_verify_pubkey(
const uint8_t *data,
size_t size) {
1045 if (size - 2 != 2 * DTLS_EC_KEY_SIZE)
1052asn1_verify_curve(
const uint8_t *data,
size_t size) {
1053 static uint8_t prime256v1_oid[] =
1055 { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 };
1058 if (size !=
sizeof(prime256v1_oid) ||
1059 memcmp(data, prime256v1_oid, size) != 0)
1066asn1_verify_pkcs8_version(
const uint8_t *data,
size_t size) {
1068 if (size != 1 || *data != 0)
1075asn1_verify_ec_identifier(
const uint8_t *data,
size_t size) {
1076 static uint8_t ec_public_key_oid[] =
1078 { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 };
1081 if (size !=
sizeof(ec_public_key_oid) ||
1082 memcmp(data, ec_public_key_oid, size) != 0)
1089asn1_verify_ec_key(
const uint8_t *data,
size_t size) {
1099asn1_derive_keys(coap_tiny_context_t *t_context,
1100 const uint8_t *priv_data,
size_t priv_len,
1101 const uint8_t *pub_data,
size_t pub_len,
1106 priv_len, asn1_verify_privkey);
1107 if (!t_context->priv_key) {
1112 if (t_context->priv_key->length - 1 == DTLS_EC_KEY_SIZE &&
1113 t_context->priv_key->s[0] ==
'\000') {
1114 t_context->priv_key->length--;
1115 t_context->priv_key->s++;
1123 coap_log_info(
"EC Private Key (RPK) invalid elliptic curve\n");
1125 t_context->priv_key = NULL;
1132 asn1_verify_pubkey);
1133 if (!t_context->pub_key) {
1136 t_context->priv_key = NULL;
1140 t_context->pub_key->s += 2;
1141 t_context->pub_key->length -= 2;
1142 dtls_set_handler(t_context->dtls_context, &ec_cb);
1147ec_abstract_pkcs8_asn1(
const uint8_t *asn1_ptr,
size_t asn1_length) {
1151 asn1_verify_pkcs8_version);
1158 asn1_verify_ec_identifier);
1166 coap_log_info(
"EC Private Key (RPK) invalid elliptic curve\n");
1172 asn1_verify_ec_key);
1177pem_decode_mem_asn1(
const char *begstr,
const uint8_t *str) {
1178 char *bcp = str ? strstr((
const char *)str, begstr) : NULL;
1179 char *tcp = bcp ? strstr(bcp,
"-----END ") : NULL;
1182 bcp += strlen(begstr);
1183 return pem_base64_decode((
const uint8_t *)bcp, tcp - bcp);
1195 coap_tiny_context_t *t_context;
1214 if (t_context->priv_key) {
1216 t_context->priv_key = NULL;
1218 if (t_context->pub_key) {
1220 t_context->pub_key = NULL;
1222 t_context->setup_data = *setup_data;
1227 coap_log_warn(
"RPK keys cannot be in COAP_PKI_KEY_PEM format\n");
1235 asn1_priv = pem_decode_mem_asn1(
"-----BEGIN EC PRIVATE KEY-----",
1238 asn1_priv = pem_decode_mem_asn1(
"-----BEGIN PRIVATE KEY-----",
1244 asn1_temp = ec_abstract_pkcs8_asn1(asn1_priv->
s, asn1_priv->
length);
1251 asn1_priv = asn1_temp;
1254 asn1_pub = pem_decode_mem_asn1(
1255 "-----BEGIN PUBLIC KEY-----",
1258 asn1_pub = pem_decode_mem_asn1(
"-----BEGIN EC PRIVATE KEY-----",
1261 asn1_pub = pem_decode_mem_asn1(
"-----BEGIN PRIVATE KEY-----",
1268 asn1_temp = ec_abstract_pkcs8_asn1(asn1_pub->
s, asn1_pub->
length);
1276 asn1_pub = asn1_temp;
1280 if (!asn1_derive_keys(t_context, asn1_priv->
s, asn1_priv->
length,
1281 asn1_pub->
s, asn1_pub->
length, is_pkcs8)) {
1300 asn1_temp = ec_abstract_pkcs8_asn1(
1304 private_key = asn1_temp->
s;
1305 private_key_len = asn1_temp->
length;
1311 if (!asn1_derive_keys(t_context,
1323 if (!asn1_derive_keys(t_context,
1339 coap_log_warn(
"RPK keys cannot be in COAP_PKI_KEY_PCKS11 format\n");
1361#if COAP_CLIENT_SUPPORT
1378#if COAP_SERVER_SUPPORT
1388 coap_log_warn(
"CoAP Server with TinyDTLS does not support SNI selection\n");
1404#if !COAP_DISABLE_TCP
1405#if COAP_CLIENT_SUPPORT
1412#if COAP_SERVER_SUPPORT
1450#if COAP_SERVER_SUPPORT
1456 dtls_sha256_init(digest_ctx);
1469 const uint8_t *data,
1471 dtls_sha256_update(digest_ctx, data, data_len);
1479 dtls_sha256_final((uint8_t *)digest_buffer, digest_ctx);
1498#if COAP_OSCORE_SUPPORT
1510static struct cipher_algs {
1521 for (idx = 0; idx <
sizeof(ciphers)/
sizeof(
struct cipher_algs); idx++) {
1522 if (ciphers[idx].alg == alg)
1523 return ciphers[idx].cipher_type;
1525 coap_log_debug(
"get_cipher_alg: COSE cipher %d not supported\n", alg);
1534static struct hmac_algs {
1545 for (idx = 0; idx <
sizeof(hmacs)/
sizeof(
struct hmac_algs); idx++) {
1546 if (hmacs[idx].hmac_alg == hmac_alg)
1547 return hmacs[idx].hmac_type;
1549 coap_log_debug(
"get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg);
1555 return get_cipher_alg(alg);
1564 return get_hmac_alg(hmac_alg);
1571 uint8_t *result,
size_t *max_result_len) {
1574 dtls_ccm_params_t dtls_params;
1582 if (get_cipher_alg(params->
alg) == 0) {
1583 coap_log_debug(
"coap_crypto_encrypt: algorithm %d not supported\n",
1594 dtls_params.nonce = ccm->
nonce;
1595 dtls_params.tag_length = ccm->
tag_len;
1596 dtls_params.l = ccm->
l;
1605 num_bytes = dtls_encrypt_params(&dtls_params,
1610 if (num_bytes < 0) {
1613 *max_result_len = num_bytes;
1621 uint8_t *result,
size_t *max_result_len) {
1624 dtls_ccm_params_t dtls_params;
1632 if (get_cipher_alg(params->
alg) == 0) {
1633 coap_log_debug(
"coap_crypto_decrypt: algorithm %d not supported\n",
1645 dtls_params.nonce = ccm->
nonce;
1646 dtls_params.tag_length = ccm->
tag_len;
1647 dtls_params.l = ccm->
l;
1656 num_bytes = dtls_decrypt_params(&dtls_params,
1661 if (num_bytes < 0) {
1664 *max_result_len = num_bytes;
1671 dtls_hmac_context_t hmac_context;
1678 if (get_hmac_alg(hmac_alg) == 0) {
1679 coap_log_debug(
"coap_crypto_hmac: algorithm %d not supported\n", hmac_alg);
1687 dtls_hmac_init(&hmac_context, key->
s, key->
length);
1688 dtls_hmac_update(&hmac_context, data->
s, data->
length);
1689 num_bytes = dtls_hmac_finalize(&hmac_context,
dummy->s);
1691 if (num_bytes != DTLS_SHA256_DIGEST_LENGTH) {
1707#pragma GCC diagnostic ignored "-Wunused-function"
Pulls together all the internal only header files.
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().
int coap_dtls_context_set_pki(coap_context_t *ctx COAP_UNUSED, const coap_dtls_pki_t *setup_data COAP_UNUSED, const coap_dtls_role_t role COAP_UNUSED)
coap_tick_t coap_dtls_get_timeout(coap_session_t *session COAP_UNUSED, coap_tick_t now COAP_UNUSED)
ssize_t coap_tls_read(coap_session_t *session COAP_UNUSED, uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context COAP_UNUSED)
int coap_dtls_receive(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
void * coap_dtls_get_tls(const coap_session_t *c_session COAP_UNUSED, coap_tls_library_t *tls_lib)
unsigned int coap_dtls_get_overhead(coap_session_t *session COAP_UNUSED)
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx COAP_UNUSED)
ssize_t coap_dtls_send(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
ssize_t coap_tls_write(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
void coap_dtls_session_update_mtu(coap_session_t *session COAP_UNUSED)
int coap_dtls_context_set_pki_root_cas(coap_context_t *ctx COAP_UNUSED, const char *ca_file COAP_UNUSED, const char *ca_path COAP_UNUSED)
int coap_dtls_handle_timeout(coap_session_t *session COAP_UNUSED)
void coap_dtls_free_context(void *handle COAP_UNUSED)
void coap_dtls_free_session(coap_session_t *coap_session COAP_UNUSED)
void * coap_dtls_new_context(coap_context_t *coap_context COAP_UNUSED)
void coap_tls_free_session(coap_session_t *coap_session COAP_UNUSED)
coap_binary_t * get_asn1_tag(coap_asn1_tag_t ltag, const uint8_t *ptr, size_t tlen, asn1_validate validate)
Get the asn1 tag and data from the current ptr.
void coap_digest_free(coap_digest_ctx_t *digest_ctx)
Free off coap_digest_ctx_t.
int coap_digest_final(coap_digest_ctx_t *digest_ctx, coap_digest_t *digest_buffer)
Finalize the coap_digest information into the provided digest_buffer.
int coap_digest_update(coap_digest_ctx_t *digest_ctx, const uint8_t *data, size_t data_len)
Update the coap_digest information with the next chunk of data.
coap_digest_ctx_t * coap_digest_setup(void)
Initialize a coap_digest.
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
#define COAP_TICKS_PER_SECOND
Use ms resolution on POSIX systems.
int coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, uint8_t *msg, size_t msg_len)
Parses and interprets a CoAP datagram with context ctx.
int coap_handle_event(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
void coap_ticks(coap_tick_t *)
Returns the current value of an internal tick counter.
int coap_crypto_hmac(cose_hmac_alg_t hmac_alg, coap_bin_const_t *key, coap_bin_const_t *data, coap_bin_const_t **hmac)
Create a HMAC hash of the provided data.
int coap_crypto_aead_decrypt(const coap_crypto_param_t *params, coap_bin_const_t *data, coap_bin_const_t *aad, uint8_t *result, size_t *max_result_len)
Decrypt the provided encrypted data into plaintext.
int coap_crypto_aead_encrypt(const coap_crypto_param_t *params, coap_bin_const_t *data, coap_bin_const_t *aad, uint8_t *result, size_t *max_result_len)
Encrypt the provided plaintext data.
int coap_crypto_hash(cose_alg_t alg, const coap_bin_const_t *data, coap_bin_const_t **hash)
Create a hash of the provided data.
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.
void * coap_tls_new_server_session(coap_session_t *coap_session)
Create a TLS new server-side session.
const coap_bin_const_t * coap_get_session_client_psk_identity(const coap_session_t *session)
Get the current client's PSK identity.
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
void * coap_dtls_new_client_session(coap_session_t *coap_session)
Create a new client-side session.
void * coap_dtls_new_server_session(coap_session_t *coap_session)
Create a new DTLS server-side session.
int coap_dtls_hello(coap_session_t *coap_session, const uint8_t *data, size_t data_len)
Handling client HELLO messages from a new candiate peer.
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
int coap_dtls_context_set_cpsk(coap_context_t *coap_context, coap_dtls_cpsk_t *setup_data)
Set the DTLS context's default client PSK information.
int coap_dtls_context_set_spsk(coap_context_t *coap_context, coap_dtls_spsk_t *setup_data)
Set the DTLS context's default server PSK information.
void coap_dtls_shutdown(void)
Close down the underlying (D)TLS Library layer.
const coap_bin_const_t * coap_get_session_client_psk_key(const coap_session_t *coap_session)
Get the current client's PSK key.
void * coap_tls_new_client_session(coap_session_t *coap_session)
Create a new TLS client-side session.
const coap_bin_const_t * coap_get_session_server_psk_key(const coap_session_t *coap_session)
Get the current server's PSK key.
const coap_bin_const_t * coap_get_session_server_psk_hint(const coap_session_t *coap_session)
Get the current server's PSK identity hint.
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
int coap_dtls_psk_is_supported(void)
Check whether (D)TLS PSK is available.
int coap_tls_is_supported(void)
Check whether TLS is available.
#define COAP_DTLS_PKI_SETUP_VERSION
Latest PKI setup version.
#define COAP_DTLS_RPK_CERT_CN
int coap_dtls_is_supported(void)
Check whether DTLS is available.
int coap_dtls_pki_is_supported(void)
Check whether (D)TLS PKI is available.
int coap_dtls_rpk_is_supported(void)
Check whether (D)TLS RPK is available.
int coap_dtls_pkcs11_is_supported(void)
Check whether (D)TLS PKCS11 is available.
@ COAP_PKI_KEY_PKCS11
The PKI key type is PKCS11 (DER)
@ COAP_PKI_KEY_PEM_BUF
The PKI key type is PEM buffer.
@ COAP_PKI_KEY_PEM
The PKI key type is PEM file.
@ COAP_PKI_KEY_ASN1
The PKI key type is ASN.1 (DER) buffer.
@ COAP_ASN1_PKEY_EC
EC type.
@ COAP_TLS_LIBRARY_TINYDTLS
Using TinyDTLS library.
@ COAP_EVENT_DTLS_CLOSED
Triggerred when (D)TLS session closed.
@ COAP_EVENT_DTLS_CONNECTED
Triggered when (D)TLS session connected.
@ COAP_EVENT_DTLS_RENEGOTIATE
Triggered when (D)TLS session renegotiated.
@ COAP_EVENT_DTLS_ERROR
Triggered when (D)TLS error occurs.
#define coap_log_debug(...)
coap_log_t coap_dtls_get_log_level(void)
Get the current (D)TLS logging.
#define coap_dtls_log(level,...)
Logging function.
void coap_dtls_set_log_level(coap_log_t level)
Sets the (D)TLS logging level to the specified level.
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log_info(...)
#define coap_log_warn(...)
int cose_get_hmac_alg_for_hkdf(cose_hkdf_alg_t hkdf_alg, cose_hmac_alg_t *hmac_alg)
@ COSE_HMAC_ALG_HMAC256_256
@ COSE_ALGORITHM_AES_CCM_16_64_128
int coap_oscore_is_supported(void)
Check whether OSCORE is available.
int coap_session_refresh_psk_hint(coap_session_t *session, const coap_bin_const_t *psk_hint)
Refresh the session's current Identity Hint (PSK).
int coap_session_refresh_psk_key(coap_session_t *session, const coap_bin_const_t *psk_key)
Refresh the session's current pre-shared key (PSK).
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
int coap_session_refresh_psk_identity(coap_session_t *session, const coap_bin_const_t *psk_identity)
Refresh the session's current pre-shared identity (PSK).
coap_session_t * coap_session_get_by_peer(const coap_context_t *ctx, const coap_address_t *remote_addr, int ifindex)
Get the session associated with the specified remote_addr and index.
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
@ COAP_SESSION_TYPE_CLIENT
client-side
coap_binary_t * coap_new_binary(size_t size)
Returns a new binary object with at least size bytes storage allocated.
void coap_delete_binary(coap_binary_t *s)
Deletes the given coap_binary_t object and releases any memory allocated.
coap_address_t remote
remote address and port
Multi-purpose address abstraction.
socklen_t size
size of addr
union coap_address_t::@0 addr
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.
coap_dtls_spsk_t spsk_setup_data
Contains the initial PSK server setup data.
The structure that holds the AES Crypto information.
size_t l
The number of bytes in the length field.
const uint8_t * nonce
must be exactly 15 - l bytes
coap_crypto_key_t key
The Key to use.
size_t tag_len
The size of the Tag.
The common structure that holds the Crypto information.
union coap_crypto_param_t::@2 params
coap_crypto_aes_ccm_t aes
Used if AES type encryption.
cose_alg_t alg
The COSE algorith to use.
The structure that holds the Client PSK information.
coap_bin_const_t identity
The structure used for defining the Client PSK setup data to be used.
void * ih_call_back_arg
Passed in to the Identity Hint callback function.
coap_dtls_ih_callback_t validate_ih_call_back
Identity Hint check callback function.
union coap_dtls_key_t::@3 key
coap_pki_key_pem_buf_t pem_buf
for PEM memory keys
coap_pki_key_t key_type
key format type
coap_pki_key_asn1_t asn1
for ASN.1 (DER) memory keys
The structure used for defining the PKI setup data to be used.
uint8_t is_rpk_not_cert
1 is RPK instead of Public Certificate.
coap_dtls_key_t pki_key
PKI key definition.
The structure used for defining the Server PSK setup data to be used.
coap_dtls_psk_sni_callback_t validate_sni_call_back
SNI check callback function.
coap_dtls_id_callback_t validate_id_call_back
Identity check callback function.
void * id_call_back_arg
Passed in to the Identity callback function.
coap_layer_write_t l_write
const uint8_t * private_key
ASN1 (DER) Private Key.
coap_asn1_privatekey_type_t private_key_type
Private Key Type.
size_t public_cert_len
ASN1 Public Cert length.
size_t private_key_len
ASN1 Private Key length.
const uint8_t * public_cert
ASN1 (DER) Public Cert, or Public Key if RPK.
const uint8_t * private_key
PEM buffer Private Key If RPK and 'EC PRIVATE KEY' this can be used for both the public_cert and priv...
const uint8_t * public_cert
PEM buffer Public Cert, or Public Key if RPK.
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
coap_socket_t sock
socket object for the session, if any
coap_addr_tuple_t addr_info
remote/local address info
coap_dtls_cpsk_t cpsk_setup_data
client provided PSK initial setup data
void * tls
security parameters
coap_session_type_t type
client or server side socket
coap_context_t * context
session's context
int ifindex
interface index
coap_layer_func_t lfunc[COAP_LAYER_LAST]
Layer functions to use.
CoAP string data definition with const data.
const uint8_t * s
read-only string data
size_t length
length of string
The structure used for returning the underlying (D)TLS library information.
uint64_t built_version
(D)TLS Built against Library Version
coap_tls_library_t type
Library type.
uint64_t version
(D)TLS runtime Library Version