libcoap 4.3.5-develop-72190a8
Loading...
Searching...
No Matches
coap_mbedtls.c
Go to the documentation of this file.
1/*
2 * coap_mbedtls.c -- Mbed TLS Datagram Transport Layer Support for libcoap
3 *
4 * Copyright (C) 2019-2024 Jon Shallow <supjps-libcoap@jpshallow.com>
5 * 2019 Jitin George <jitin@espressif.com>
6 *
7 * SPDX-License-Identifier: BSD-2-Clause
8 *
9 * This file is part of the CoAP library libcoap. Please see README for terms
10 * of use.
11 */
12
18/*
19 * Naming used to prevent confusion between coap sessions, mbedtls sessions etc.
20 * when reading the code.
21 *
22 * c_context A coap_context_t *
23 * c_session A coap_session_t *
24 * m_context A coap_mbedtls_context_t * (held in c_context->dtls_context)
25 * m_env A coap_mbedtls_env_t * (held in c_session->tls)
26 */
27
28/*
29 * Notes
30 *
31 * Version 3.2.0 or later is needed to provide Connection ID support (RFC9146).
32 *
33 */
34
36
37#ifdef COAP_WITH_LIBMBEDTLS
38
39/*
40 * This code can be conditionally compiled to remove some components if
41 * they are not required to make a lighter footprint - all based on how
42 * the mbedtls library has been built. These are not defined within the
43 * libcoap environment.
44 *
45 * MBEDTLS_SSL_SRV_C - defined for server side functionality
46 * MBEDTLS_SSL_CLI_C - defined for client side functionality
47 * MBEDTLS_SSL_PROTO_DTLS - defined for DTLS support
48 * MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED - defined if PSK is to be supported
49 * or MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED - defined if PSK is to be supported
50 *
51 */
52
53#include <mbedtls/version.h>
54
55/* Keep forward-compatibility with Mbed TLS 3.x */
56#if (MBEDTLS_VERSION_NUMBER < 0x03000000)
57#define MBEDTLS_2_X_COMPAT
58#else /* !(MBEDTLS_VERSION_NUMBER < 0x03000000) */
59/* Macro wrapper for struct's private members */
60#ifndef MBEDTLS_ALLOW_PRIVATE_ACCESS
61#define MBEDTLS_ALLOW_PRIVATE_ACCESS
62#endif /* MBEDTLS_ALLOW_PRIVATE_ACCESS */
63#endif /* !(MBEDTLS_VERSION_NUMBER < 0x03000000) */
64
65#include <mbedtls/platform.h>
66#include <mbedtls/net_sockets.h>
67#include <mbedtls/ssl.h>
68#include <mbedtls/entropy.h>
69#include <mbedtls/ctr_drbg.h>
70#include <mbedtls/error.h>
71#include <mbedtls/timing.h>
72#include <mbedtls/ssl_cookie.h>
73#include <mbedtls/oid.h>
74#include <mbedtls/debug.h>
75#include <mbedtls/sha256.h>
76#if defined(ESPIDF_VERSION) && defined(CONFIG_MBEDTLS_DEBUG)
77#include <mbedtls/esp_debug.h>
78#endif /* ESPIDF_VERSION && CONFIG_MBEDTLS_DEBUG */
79#if defined(MBEDTLS_PSA_CRYPTO_C)
80#include <psa/crypto.h>
81#endif /* MBEDTLS_PSA_CRYPTO_C */
82
83#define mbedtls_malloc(a) malloc(a)
84#define mbedtls_realloc(a,b) realloc(a,b)
85#define mbedtls_strdup(a) strdup(a)
86#define mbedtls_strndup(a,b) strndup(a,b)
87#undef mbedtls_free
88#define mbedtls_free(a) free(a)
89
90#ifndef MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
91/* definition changed in later mbedtls code versions */
92#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
93#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
94#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
95#endif /* ! MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
96
97#if ! COAP_SERVER_SUPPORT
98#undef MBEDTLS_SSL_SRV_C
99#endif /* ! COAP_SERVER_SUPPORT */
100#if ! COAP_CLIENT_SUPPORT
101#undef MBEDTLS_SSL_CLI_C
102#endif /* ! COAP_CLIENT_SUPPORT */
103
104#ifdef _WIN32
105#define strcasecmp _stricmp
106#endif
107
108#define IS_PSK (1 << 0)
109#define IS_PKI (1 << 1)
110#define IS_CLIENT (1 << 6)
111#define IS_SERVER (1 << 7)
112
113typedef struct coap_ssl_t {
114 const uint8_t *pdu;
115 unsigned pdu_len;
116 unsigned peekmode;
117} coap_ssl_t;
118
119/*
120 * This structure encapsulates the Mbed TLS session object.
121 * It handles both TLS and DTLS.
122 * c_session->tls points to this.
123 */
124typedef struct coap_mbedtls_env_t {
125 mbedtls_ssl_context ssl;
126 mbedtls_entropy_context entropy;
127 mbedtls_ctr_drbg_context ctr_drbg;
128 mbedtls_ssl_config conf;
129 mbedtls_timing_delay_context timer;
130 mbedtls_x509_crt cacert;
131 mbedtls_x509_crt public_cert;
132 mbedtls_pk_context private_key;
133 mbedtls_ssl_cookie_ctx cookie_ctx;
134 /* If not set, need to do do_mbedtls_handshake */
135 int established;
136 int sent_alert;
137 int seen_client_hello;
138 int ec_jpake;
139 coap_tick_t last_timeout;
140 unsigned int retry_scalar;
141 coap_ssl_t coap_ssl_data;
142 uint32_t server_hello_cnt;
143} coap_mbedtls_env_t;
144
145typedef struct pki_sni_entry {
146 char *sni;
147 coap_dtls_key_t pki_key;
148 mbedtls_x509_crt cacert;
149 mbedtls_x509_crt public_cert;
150 mbedtls_pk_context private_key;
151} pki_sni_entry;
152
153typedef struct psk_sni_entry {
154 char *sni;
155 coap_dtls_spsk_info_t psk_info;
156} psk_sni_entry;
157
158typedef struct coap_mbedtls_context_t {
159 coap_dtls_pki_t setup_data;
160 size_t pki_sni_count;
161 pki_sni_entry *pki_sni_entry_list;
162 size_t psk_sni_count;
163 psk_sni_entry *psk_sni_entry_list;
164 char *root_ca_file;
165 char *root_ca_path;
166 int psk_pki_enabled;
167} coap_mbedtls_context_t;
168
169typedef enum coap_enc_method_t {
170 COAP_ENC_PSK,
171 COAP_ENC_PKI,
172 COAP_ENC_ECJPAKE,
173} coap_enc_method_t;
174
175#ifndef MBEDTLS_2_X_COMPAT
176/*
177 * mbedtls_ callback functions expect 0 on success, -ve on failure.
178 */
179static int
180coap_rng(void *ctx COAP_UNUSED, unsigned char *buf, size_t len) {
181 return coap_prng_lkd(buf, len) ? 0 : MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
182}
183#endif /* MBEDTLS_2_X_COMPAT */
184
185static int
186coap_dgram_read(void *ctx, unsigned char *out, size_t outl) {
187 ssize_t ret = 0;
188 coap_session_t *c_session = (coap_session_t *)ctx;
189 coap_ssl_t *data;
190
191 if (!c_session->tls) {
192 errno = EAGAIN;
193 return MBEDTLS_ERR_SSL_WANT_READ;
194 }
195 data = &((coap_mbedtls_env_t *)c_session->tls)->coap_ssl_data;
196
197 if (out != NULL) {
198 if (data->pdu_len > 0) {
199 if (outl < data->pdu_len) {
200 memcpy(out, data->pdu, outl);
201 ret = outl;
202 data->pdu += outl;
203 data->pdu_len -= outl;
204 } else {
205 memcpy(out, data->pdu, data->pdu_len);
206 ret = data->pdu_len;
207 if (!data->peekmode) {
208 data->pdu_len = 0;
209 data->pdu = NULL;
210 }
211 }
212 } else {
213 ret = MBEDTLS_ERR_SSL_WANT_READ;
214 errno = EAGAIN;
215 }
216 }
217 return ret;
218}
219
220/*
221 * return +ve data amount
222 * 0 no more
223 * -ve Mbed TLS error
224 */
225/* callback function given to mbedtls for sending data over socket */
226static int
227coap_dgram_write(void *ctx, const unsigned char *send_buffer,
228 size_t send_buffer_length) {
229 ssize_t result = -1;
230 coap_session_t *c_session = (coap_session_t *)ctx;
231
232 if (c_session) {
233 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
234
235 if (!coap_netif_available(c_session)
237 && c_session->endpoint == NULL
238#endif /* COAP_SERVER_SUPPORT */
239 ) {
240 /* socket was closed on client due to error */
241 errno = ECONNRESET;
242 return -1;
243 }
244 result = (int)c_session->sock.lfunc[COAP_LAYER_TLS].l_write(c_session,
245 send_buffer, send_buffer_length);
246 if (result != (ssize_t)send_buffer_length) {
247 int keep_errno = errno;
248
249 coap_log_warn("coap_netif_dgrm_write failed (%zd != %zu)\n",
250 result, send_buffer_length);
251 errno = keep_errno;
252 if (result < 0) {
253 return -1;
254 } else {
255 result = 0;
256 }
257 } else if (m_env) {
258 coap_tick_t now;
259 coap_ticks(&now);
260 m_env->last_timeout = now;
261 }
262 } else {
263 result = 0;
264 }
265 return result;
266}
267
268#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && defined(MBEDTLS_SSL_SRV_C)
269/*
270 * Server side PSK callback
271 */
272static int
273psk_server_callback(void *p_info, mbedtls_ssl_context *ssl,
274 const unsigned char *identity, size_t identity_len) {
275 coap_session_t *c_session = (coap_session_t *)p_info;
276 coap_dtls_spsk_t *setup_data;
277 coap_mbedtls_env_t *m_env;
278 coap_bin_const_t lidentity;
279 const coap_bin_const_t *psk_key;
280
281 if (c_session == NULL)
282 return -1;
283
284 /* Track the Identity being used */
285 lidentity.s = identity ? (const uint8_t *)identity : (const uint8_t *)"";
286 lidentity.length = identity ? identity_len : 0;
287 coap_session_refresh_psk_identity(c_session, &lidentity);
288
289 coap_log_debug("got psk_identity: '%.*s'\n",
290 (int)lidentity.length, (const char *)lidentity.s);
291
292 m_env = (coap_mbedtls_env_t *)c_session->tls;
293 setup_data = &c_session->context->spsk_setup_data;
294
295 if (setup_data->validate_id_call_back) {
296 psk_key = setup_data->validate_id_call_back(&lidentity,
297 c_session,
298 setup_data->id_call_back_arg);
299
300 coap_session_refresh_psk_key(c_session, psk_key);
301 } else {
302 psk_key = coap_get_session_server_psk_key(c_session);
303 }
304
305 if (psk_key == NULL)
306 return -1;
307 mbedtls_ssl_set_hs_psk(ssl, psk_key->s, psk_key->length);
308 m_env->seen_client_hello = 1;
309 return 0;
310}
311#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED && MBEDTLS_SSL_SRV_C */
312
313static char *
314get_san_or_cn_from_cert(mbedtls_x509_crt *crt) {
315 if (crt) {
316 const mbedtls_asn1_named_data *cn_data;
317
318 if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
319 mbedtls_asn1_sequence *seq = &crt->subject_alt_names;
320 while (seq && seq->buf.p == NULL) {
321 seq = seq->next;
322 }
323 if (seq) {
324 /* Return the Subject Alt Name */
325 return mbedtls_strndup((const char *)seq->buf.p,
326 seq->buf.len);
327 }
328 }
329
330 cn_data = mbedtls_asn1_find_named_data(&crt->subject,
331 MBEDTLS_OID_AT_CN,
332 MBEDTLS_OID_SIZE(MBEDTLS_OID_AT_CN));
333 if (cn_data) {
334 /* Return the Common Name */
335 return mbedtls_strndup((const char *)cn_data->val.p,
336 cn_data->val.len);
337 }
338 }
339 return NULL;
340}
341
342#if COAP_MAX_LOGGING_LEVEL > 0
343static char *
344get_error_string(int ret) {
345 static char buf[128] = {0};
346 mbedtls_strerror(ret, buf, sizeof(buf)-1);
347 return buf;
348}
349#endif /* COAP_MAX_LOGGING_LEVEL */
350
351static int
352self_signed_cert_verify_callback_mbedtls(void *data,
353 mbedtls_x509_crt *crt COAP_UNUSED,
354 int depth COAP_UNUSED,
355 uint32_t *flags) {
356 const coap_session_t *c_session = (coap_session_t *)data;
357 const coap_mbedtls_context_t *m_context =
358 (coap_mbedtls_context_t *)c_session->context->dtls_context;
359 const coap_dtls_pki_t *setup_data = &m_context->setup_data;
360
361 if (*flags & MBEDTLS_X509_BADCERT_EXPIRED) {
362 if (setup_data->allow_expired_certs) {
363 *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED;
364 }
365 }
366 return 0;
367}
368
369/*
370 * return 0 All OK
371 * -ve Error Code
372 */
373static int
374cert_verify_callback_mbedtls(void *data, mbedtls_x509_crt *crt,
375 int depth, uint32_t *flags) {
376 coap_session_t *c_session = (coap_session_t *)data;
377 coap_mbedtls_context_t *m_context =
378 (coap_mbedtls_context_t *)c_session->context->dtls_context;
379 coap_dtls_pki_t *setup_data = &m_context->setup_data;
380 char *cn = NULL;
381
382 if (*flags == 0)
383 return 0;
384
385 cn = get_san_or_cn_from_cert(crt);
386
387 if (*flags & MBEDTLS_X509_BADCERT_EXPIRED) {
388 if (setup_data->allow_expired_certs) {
389 *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED;
390 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
391 coap_session_str(c_session),
392 "The certificate has expired", cn ? cn : "?", depth);
393 }
394 }
395 if (*flags & MBEDTLS_X509_BADCERT_FUTURE) {
396 if (setup_data->allow_expired_certs) {
397 *flags &= ~MBEDTLS_X509_BADCERT_FUTURE;
398 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
399 coap_session_str(c_session),
400 "The certificate has a future date", cn ? cn : "?", depth);
401 }
402 }
403 if (*flags & MBEDTLS_X509_BADCERT_BAD_MD) {
404 if (setup_data->allow_bad_md_hash) {
405 *flags &= ~MBEDTLS_X509_BADCERT_BAD_MD;
406 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
407 coap_session_str(c_session),
408 "The certificate has a bad MD hash", cn ? cn : "?", depth);
409 }
410 }
411 if (*flags & MBEDTLS_X509_BADCERT_BAD_KEY) {
412 if (setup_data->allow_short_rsa_length) {
413 *flags &= ~MBEDTLS_X509_BADCERT_BAD_KEY;
414 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
415 coap_session_str(c_session),
416 "The certificate has a short RSA length", cn ? cn : "?", depth);
417 }
418 }
419 if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
420 uint32_t lflags;
421 int self_signed = !mbedtls_x509_crt_verify(crt, crt, NULL, NULL, &lflags,
422 self_signed_cert_verify_callback_mbedtls,
423 data);
424 if (self_signed && depth == 0) {
425 if (setup_data->allow_self_signed &&
426 !setup_data->check_common_ca) {
427 *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
428 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
429 coap_session_str(c_session),
430 "Self-signed",
431 cn ? cn : "?", depth);
432 }
433 } else if (self_signed) {
434 if (!setup_data->verify_peer_cert) {
435 *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
436 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
437 coap_session_str(c_session),
438 "Self-signed", cn ? cn : "?", depth);
439 }
440 } else {
441 if (!setup_data->verify_peer_cert) {
442 *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
443 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
444 coap_session_str(c_session),
445 "The certificate's CA is not trusted", cn ? cn : "?", depth);
446 }
447 }
448 }
449 if (*flags & MBEDTLS_X509_BADCRL_EXPIRED) {
450 if (setup_data->check_cert_revocation && setup_data->allow_expired_crl) {
451 *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED;
452 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
453 coap_session_str(c_session),
454 "The certificate's CRL has expired", cn ? cn : "?", depth);
455 } else if (!setup_data->check_cert_revocation) {
456 *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED;
457 }
458 }
459 if (*flags & MBEDTLS_X509_BADCRL_FUTURE) {
460 if (setup_data->check_cert_revocation && setup_data->allow_expired_crl) {
461 *flags &= ~MBEDTLS_X509_BADCRL_FUTURE;
462 coap_log_info(" %s: %s: overridden: '%s' depth %d\n",
463 coap_session_str(c_session),
464 "The certificate's CRL has a future date", cn ? cn : "?", depth);
465 } else if (!setup_data->check_cert_revocation) {
466 *flags &= ~MBEDTLS_X509_BADCRL_FUTURE;
467 }
468 }
469 if (setup_data->cert_chain_validation &&
470 depth > (setup_data->cert_chain_verify_depth + 1)) {
471 *flags |= MBEDTLS_X509_BADCERT_OTHER;
472 coap_log_warn(" %s: %s: '%s' depth %d\n",
473 coap_session_str(c_session),
474 "The certificate's verify depth is too long",
475 cn ? cn : "?", depth);
476 }
477
478 if (*flags & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
479 *flags &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH;
480 }
481 if (setup_data->validate_cn_call_back) {
482 int ret;
483
484 coap_lock_callback_ret(ret, c_session->context,
485 setup_data->validate_cn_call_back(cn,
486 crt->raw.p,
487 crt->raw.len,
488 c_session,
489 depth,
490 *flags == 0,
491 setup_data->cn_call_back_arg));
492 if (!ret) {
493 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
494 }
495 }
496 if (*flags != 0) {
497 char buf[128];
498 char *tcp;
499 int ret = mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", *flags);
500
501 if (ret >= 0) {
502 tcp = strchr(buf, '\n');
503 while (tcp) {
504 *tcp = '\000';
505 coap_log_warn(" %s: %s: issue 0x%" PRIx32 ": '%s' depth %d\n",
506 coap_session_str(c_session),
507 buf, *flags, cn ? cn : "?", depth);
508 tcp = strchr(tcp+1, '\n');
509 }
510 } else {
511 coap_log_err("mbedtls_x509_crt_verify_info returned -0x%x: '%s'\n",
512 -ret, get_error_string(ret));
513 }
514 }
515
516 if (cn)
517 mbedtls_free(cn);
518
519 return 0;
520}
521
522static int
523setup_pki_credentials(mbedtls_x509_crt *cacert,
524 mbedtls_x509_crt *public_cert,
525 mbedtls_pk_context *private_key,
526 coap_mbedtls_env_t *m_env,
527 coap_mbedtls_context_t *m_context,
528 coap_session_t *c_session,
529 coap_dtls_pki_t *setup_data,
530 coap_dtls_role_t role) {
531 coap_dtls_key_t key;
532 int ret;
533 int done_private_key = 0;
534 int done_public_cert = 0;
535 uint8_t *buffer;
536 size_t length;
537
538 /* Map over to the new define format to save code duplication */
539 coap_dtls_map_key_type_to_define(setup_data, &key);
540
541 assert(key.key_type == COAP_PKI_KEY_DEFINE);
542
543 /*
544 * Configure the Private Key
545 */
546 if (key.key.define.private_key.u_byte &&
547 key.key.define.private_key.u_byte[0]) {
548 switch (key.key.define.private_key_def) {
549 case COAP_PKI_KEY_DEF_DER: /* define private key */
550 /* Fall Through */
551 case COAP_PKI_KEY_DEF_PEM: /* define private key */
552#if defined(MBEDTLS_FS_IO)
553 mbedtls_pk_init(private_key);
554#ifdef MBEDTLS_2_X_COMPAT
555 ret = mbedtls_pk_parse_keyfile(private_key,
556 key.key.define.private_key.s_byte, NULL);
557#else
558 ret = mbedtls_pk_parse_keyfile(private_key,
560 NULL, coap_rng, (void *)&m_env->ctr_drbg);
561#endif /* MBEDTLS_2_X_COMPAT */
562 if (ret < 0) {
565 &key, role, ret);
566 }
567 done_private_key = 1;
568 break;
569#else /* ! MBEDTLS_FS_IO */
572 &key, role, -1);
573#endif /* ! MBEDTLS_FS_IO */
574 case COAP_PKI_KEY_DEF_PEM_BUF: /* define private key */
575 mbedtls_pk_init(private_key);
576 length = key.key.define.private_key_len;
577 if (key.key.define.private_key.u_byte[length-1] != '\000') {
578 /* Need to allocate memory to add in NULL terminator */
579 buffer = mbedtls_malloc(length + 1);
580 if (!buffer) {
581 coap_log_err("mbedtls_malloc failed\n");
582 return 0;
583 }
584 memcpy(buffer, key.key.define.private_key.u_byte, length);
585 buffer[length] = '\000';
586 length++;
587#ifdef MBEDTLS_2_X_COMPAT
588 ret = mbedtls_pk_parse_key(private_key, buffer, length, NULL, 0);
589#else
590 ret = mbedtls_pk_parse_key(private_key, buffer, length,
591 NULL, 0, coap_rng, (void *)&m_env->ctr_drbg);
592#endif /* MBEDTLS_2_X_COMPAT */
593 mbedtls_free(buffer);
594 } else {
595#ifdef MBEDTLS_2_X_COMPAT
596 ret = mbedtls_pk_parse_key(private_key,
598 key.key.define.private_key_len, NULL, 0);
599#else
600 ret = mbedtls_pk_parse_key(private_key,
603 NULL, 0, coap_rng, (void *)&m_env->ctr_drbg);
604#endif /* MBEDTLS_2_X_COMPAT */
605 }
606 if (ret < 0) {
609 &key, role, ret);
610 }
611 done_private_key = 1;
612 break;
613 case COAP_PKI_KEY_DEF_DER_BUF: /* define private key */
614 mbedtls_pk_init(private_key);
615#ifdef MBEDTLS_2_X_COMPAT
616 ret = mbedtls_pk_parse_key(private_key,
618 key.key.define.private_key_len, NULL, 0);
619#else
620 ret = mbedtls_pk_parse_key(private_key,
622 key.key.define.private_key_len, NULL, 0, coap_rng,
623 (void *)&m_env->ctr_drbg);
624#endif /* MBEDTLS_2_X_COMPAT */
625 if (ret < 0) {
628 &key, role, ret);
629 }
630 done_private_key = 1;
631 break;
632 case COAP_PKI_KEY_DEF_RPK_BUF: /* define private key */
633 case COAP_PKI_KEY_DEF_PKCS11: /* define private key */
634 case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define private key */
635 case COAP_PKI_KEY_DEF_ENGINE: /* define private key */
636 default:
639 &key, role, -1);
640 }
641 } else if (role == COAP_DTLS_ROLE_SERVER ||
643 key.key.define.public_cert.u_byte[0])) {
646 &key, role, -1);
647 }
648
649 /*
650 * Configure the Public Certificate / Key
651 */
652 if (key.key.define.public_cert.u_byte &&
653 key.key.define.public_cert.u_byte[0]) {
654 switch (key.key.define.public_cert_def) {
655 case COAP_PKI_KEY_DEF_DER: /* define public cert */
656 /* Fall Through */
657 case COAP_PKI_KEY_DEF_PEM: /* define public cert */
658#if defined(MBEDTLS_FS_IO)
659 mbedtls_x509_crt_init(public_cert);
660 ret = mbedtls_x509_crt_parse_file(public_cert,
662 if (ret < 0) {
665 &key, role, ret);
666 }
667 done_public_cert = 1;
668 break;
669#else /* ! MBEDTLS_FS_IO */
672 &key, role, -1);
673#endif /* ! MBEDTLS_FS_IO */
674 case COAP_PKI_KEY_DEF_PEM_BUF: /* define public cert */
675 mbedtls_x509_crt_init(public_cert);
676
677 length = key.key.define.public_cert_len;
678 if (key.key.define.public_cert.u_byte[length-1] != '\000') {
679 /* Need to allocate memory to add in NULL terminator */
680 buffer = mbedtls_malloc(length + 1);
681 if (!buffer) {
682 coap_log_err("mbedtls_malloc failed\n");
683 return 0;
684 }
685 memcpy(buffer, key.key.define.public_cert.u_byte, length);
686 buffer[length] = '\000';
687 length++;
688 ret = mbedtls_x509_crt_parse(public_cert, buffer, length);
689 mbedtls_free(buffer);
690 } else {
691 ret = mbedtls_x509_crt_parse(public_cert,
694 }
695 if (ret < 0) {
698 &key, role, ret);
699 }
700 done_public_cert = 1;
701 break;
702 case COAP_PKI_KEY_DEF_RPK_BUF: /* define public cert */
705 &key, role, -1);
706 case COAP_PKI_KEY_DEF_DER_BUF: /* define public cert */
707 mbedtls_x509_crt_init(public_cert);
708 ret = mbedtls_x509_crt_parse(public_cert,
711 if (ret < 0) {
714 &key, role, ret);
715 }
716 done_public_cert = 1;
717 break;
718 case COAP_PKI_KEY_DEF_PKCS11: /* define public cert */
719 case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define public cert */
720 case COAP_PKI_KEY_DEF_ENGINE: /* define public cert */
721 default:
724 &key, role, -1);
725 }
726 } else if (role == COAP_DTLS_ROLE_SERVER ||
728 key.key.define.private_key.u_byte[0])) {
731 &key, role, -1);
732 }
733
734 if (done_private_key && done_public_cert) {
735 ret = mbedtls_ssl_conf_own_cert(&m_env->conf, public_cert, private_key);
736 if (ret < 0) {
737 coap_log_err("mbedtls_ssl_conf_own_cert returned -0x%x: '%s'\n",
738 -ret, get_error_string(ret));
739 return 0;
740 }
741 }
742
743 /*
744 * Configure the CA
745 */
746 if (
747#if MBEDTLS_VERSION_NUMBER < 0x03060000
748 setup_data->check_common_ca &&
749#endif /* MBEDTLS_VERSION_NUMBER < 0x03060000 */
750 key.key.define.ca.u_byte &&
751 key.key.define.ca.u_byte[0]) {
752 switch (key.key.define.ca_def) {
753 case COAP_PKI_KEY_DEF_DER: /* define ca */
754 /* Fall Through */
756#if defined(MBEDTLS_FS_IO)
757 mbedtls_x509_crt_init(cacert);
758 ret = mbedtls_x509_crt_parse_file(cacert,
759 key.key.define.ca.s_byte);
760 if (ret < 0) {
763 &key, role, ret);
764 }
765 mbedtls_ssl_conf_ca_chain(&m_env->conf, cacert, NULL);
766#else /* ! MBEDTLS_FS_IO */
769 &key, role, -1);
770#endif /* ! MBEDTLS_FS_IO */
771 break;
772 case COAP_PKI_KEY_DEF_PEM_BUF: /* define ca */
773 mbedtls_x509_crt_init(cacert);
774 length = key.key.define.ca_len;
775 if (key.key.define.ca.u_byte[length-1] != '\000') {
776 /* Need to allocate memory to add in NULL terminator */
777 buffer = mbedtls_malloc(length + 1);
778 if (!buffer) {
779 coap_log_err("mbedtls_malloc failed\n");
780 return 0;
781 }
782 memcpy(buffer, key.key.define.ca.u_byte, length);
783 buffer[length] = '\000';
784 length++;
785 ret = mbedtls_x509_crt_parse(cacert, buffer, length);
786 mbedtls_free(buffer);
787 } else {
788 ret = mbedtls_x509_crt_parse(cacert,
789 key.key.define.ca.u_byte,
790 key.key.define.ca_len);
791 }
792 if (ret < 0) {
795 &key, role, ret);
796 }
797 mbedtls_ssl_conf_ca_chain(&m_env->conf, cacert, NULL);
798 break;
799 case COAP_PKI_KEY_DEF_RPK_BUF: /* define ca */
802 &key, role, -1);
803 case COAP_PKI_KEY_DEF_DER_BUF: /* define ca */
804 mbedtls_x509_crt_init(cacert);
805 ret = mbedtls_x509_crt_parse(cacert,
806 key.key.define.ca.u_byte,
807 key.key.define.ca_len);
808 if (ret < 0) {
811 &key, role, ret);
812 }
813 mbedtls_ssl_conf_ca_chain(&m_env->conf, cacert, NULL);
814 break;
815 case COAP_PKI_KEY_DEF_PKCS11: /* define ca */
816 case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define ca */
817 case COAP_PKI_KEY_DEF_ENGINE: /* define ca */
818 default:
821 &key, role, -1);
822 }
823 }
824
825 /* Add in any root CA definitons */
826
827#if defined(MBEDTLS_FS_IO)
828 if (m_context->root_ca_file) {
829 ret = mbedtls_x509_crt_parse_file(cacert, m_context->root_ca_file);
830 if (ret < 0) {
834 &key, role, ret);
835 }
836 mbedtls_ssl_conf_ca_chain(&m_env->conf, cacert, NULL);
837 }
838 if (m_context->root_ca_path) {
839 ret = mbedtls_x509_crt_parse_file(cacert, m_context->root_ca_path);
840 if (ret < 0) {
844 &key, role, ret);
845 }
846 mbedtls_ssl_conf_ca_chain(&m_env->conf, cacert, NULL);
847 }
848#else /* ! MBEDTLS_FS_IO */
849 (void)m_context;
852 &key, role, -1);
853#endif /* ! MBEDTLS_FS_IO */
854
855#if defined(MBEDTLS_SSL_SRV_C)
856 mbedtls_ssl_conf_cert_req_ca_list(&m_env->conf,
857 setup_data->check_common_ca ?
858 MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED :
859 MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED);
860#endif
861 mbedtls_ssl_conf_authmode(&m_env->conf, setup_data->verify_peer_cert ?
862 MBEDTLS_SSL_VERIFY_REQUIRED :
863 MBEDTLS_SSL_VERIFY_NONE);
864 /*
865 * Verify Peer.
866 * Need to do all checking, even if setup_data->verify_peer_cert is not set
867 */
868 mbedtls_ssl_conf_verify(&m_env->conf,
869 cert_verify_callback_mbedtls, c_session);
870
871 return 1;
872}
873
874#if defined(MBEDTLS_SSL_SRV_C)
875/*
876 * PKI SNI callback.
877 */
878static int
879pki_sni_callback(void *p_info, mbedtls_ssl_context *ssl,
880 const unsigned char *uname, size_t name_len) {
881 unsigned int i;
882 coap_dtls_pki_t sni_setup_data;
883 coap_session_t *c_session = (coap_session_t *)p_info;
884 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
885 coap_mbedtls_context_t *m_context =
886 (coap_mbedtls_context_t *)c_session->context->dtls_context;
887 char *name;
888
889 name = mbedtls_malloc(name_len+1);
890 if (!name)
891 return -1;
892
893 memcpy(name, uname, name_len);
894 name[name_len] = '\000';
895
896 /* Is this a cached entry? */
897 for (i = 0; i < m_context->pki_sni_count; i++) {
898 if (strcasecmp(name, m_context->pki_sni_entry_list[i].sni) == 0) {
899 break;
900 }
901 }
902 if (i == m_context->pki_sni_count) {
903 /*
904 * New PKI SNI request
905 */
906 coap_dtls_key_t *new_entry;
907 pki_sni_entry *pki_sni_entry_list;
908
909 coap_lock_callback_ret(new_entry, c_session->context,
910 m_context->setup_data.validate_sni_call_back(name,
911 m_context->setup_data.sni_call_back_arg));
912 if (!new_entry) {
913 mbedtls_free(name);
914 return -1;
915 }
916
917 pki_sni_entry_list = mbedtls_realloc(m_context->pki_sni_entry_list,
918 (i+1)*sizeof(pki_sni_entry));
919
920 if (pki_sni_entry_list == NULL) {
921 mbedtls_free(name);
922 return -1;
923 }
924 m_context->pki_sni_entry_list = pki_sni_entry_list;
925 memset(&m_context->pki_sni_entry_list[i], 0,
926 sizeof(m_context->pki_sni_entry_list[i]));
927 m_context->pki_sni_entry_list[i].sni = name;
928 m_context->pki_sni_entry_list[i].pki_key = *new_entry;
929 sni_setup_data = m_context->setup_data;
930 sni_setup_data.pki_key = *new_entry;
931 if (setup_pki_credentials(&m_context->pki_sni_entry_list[i].cacert,
932 &m_context->pki_sni_entry_list[i].public_cert,
933 &m_context->pki_sni_entry_list[i].private_key,
934 m_env,
935 m_context,
936 c_session,
937 &sni_setup_data, COAP_DTLS_ROLE_SERVER) < 0) {
938 mbedtls_free(name);
939 return -1;
940 }
941 /* name has been absorbed into pki_sni_entry_list[].sni entry */
942 m_context->pki_sni_count++;
943 } else {
944 mbedtls_free(name);
945 }
946
947 mbedtls_ssl_set_hs_ca_chain(ssl, &m_context->pki_sni_entry_list[i].cacert,
948 NULL);
949 return mbedtls_ssl_set_hs_own_cert(ssl,
950 &m_context->pki_sni_entry_list[i].public_cert,
951 &m_context->pki_sni_entry_list[i].private_key);
952}
953
954#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
955/*
956 * PSK SNI callback.
957 */
958static int
959psk_sni_callback(void *p_info, mbedtls_ssl_context *ssl,
960 const unsigned char *uname, size_t name_len) {
961 unsigned int i;
962 coap_session_t *c_session = (coap_session_t *)p_info;
963 coap_mbedtls_context_t *m_context =
964 (coap_mbedtls_context_t *)c_session->context->dtls_context;
965 char *name;
966
967 name = mbedtls_malloc(name_len+1);
968 if (!name)
969 return -1;
970
971 memcpy(name, uname, name_len);
972 name[name_len] = '\000';
973
974 /* Is this a cached entry? */
975 for (i = 0; i < m_context->psk_sni_count; i++) {
976 if (strcasecmp(name, m_context->psk_sni_entry_list[i].sni) == 0) {
977 break;
978 }
979 }
980 if (i == m_context->psk_sni_count) {
981 /*
982 * New PSK SNI request
983 */
984 const coap_dtls_spsk_info_t *new_entry;
985 psk_sni_entry *psk_sni_entry_list;
986
987 coap_lock_callback_ret(new_entry, c_session->context,
989 c_session,
991 if (!new_entry) {
992 mbedtls_free(name);
993 return -1;
994 }
995
996 psk_sni_entry_list = mbedtls_realloc(m_context->psk_sni_entry_list,
997 (i+1)*sizeof(psk_sni_entry));
998
999 if (psk_sni_entry_list == NULL) {
1000 mbedtls_free(name);
1001 return -1;
1002 }
1003 m_context->psk_sni_entry_list = psk_sni_entry_list;
1004 m_context->psk_sni_entry_list[i].sni = name;
1005 m_context->psk_sni_entry_list[i].psk_info = *new_entry;
1006 /* name has been absorbed into psk_sni_entry_list[].sni entry */
1007 m_context->psk_sni_count++;
1008 } else {
1009 mbedtls_free(name);
1010 }
1011
1013 &m_context->psk_sni_entry_list[i].psk_info.hint);
1015 &m_context->psk_sni_entry_list[i].psk_info.key);
1016 return mbedtls_ssl_set_hs_psk(ssl,
1017 m_context->psk_sni_entry_list[i].psk_info.key.s,
1018 m_context->psk_sni_entry_list[i].psk_info.key.length);
1019}
1020#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
1021
1022static int
1023setup_server_ssl_session(coap_session_t *c_session,
1024 coap_mbedtls_env_t *m_env) {
1025 coap_mbedtls_context_t *m_context =
1026 (coap_mbedtls_context_t *)c_session->context->dtls_context;
1027 int ret = 0;
1028 m_context->psk_pki_enabled |= IS_SERVER;
1029
1030 mbedtls_ssl_cookie_init(&m_env->cookie_ctx);
1031 if ((ret = mbedtls_ssl_config_defaults(&m_env->conf,
1032 MBEDTLS_SSL_IS_SERVER,
1033 c_session->proto == COAP_PROTO_DTLS ?
1034 MBEDTLS_SSL_TRANSPORT_DATAGRAM :
1035 MBEDTLS_SSL_TRANSPORT_STREAM,
1036 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
1037 coap_log_err("mbedtls_ssl_config_defaults returned -0x%x: '%s'\n",
1038 -ret, get_error_string(ret));
1039 goto fail;
1040 }
1041
1042 mbedtls_ssl_conf_rng(&m_env->conf, mbedtls_ctr_drbg_random, &m_env->ctr_drbg);
1043
1044#if defined(MBEDTLS_SSL_PROTO_DTLS)
1045 mbedtls_ssl_conf_handshake_timeout(&m_env->conf, COAP_DTLS_RETRANSMIT_MS,
1046 COAP_DTLS_RETRANSMIT_TOTAL_MS);
1047#endif /* MBEDTLS_SSL_PROTO_DTLS */
1048
1049 if (m_context->psk_pki_enabled & IS_PSK) {
1050#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1051 mbedtls_ssl_conf_psk_cb(&m_env->conf, psk_server_callback, c_session);
1053 mbedtls_ssl_conf_sni(&m_env->conf, psk_sni_callback, c_session);
1054 }
1055#ifdef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
1056 m_env->ec_jpake = c_session->context->spsk_setup_data.ec_jpake;
1057#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1058#else /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
1059 coap_log_warn("PSK not enabled in Mbed TLS library\n");
1060#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
1061 }
1062
1063 if (m_context->psk_pki_enabled & IS_PKI) {
1064 ret = setup_pki_credentials(&m_env->cacert, &m_env->public_cert,
1065 &m_env->private_key, m_env, m_context,
1066 c_session, &m_context->setup_data,
1068 if (ret < 0) {
1069 coap_log_err("PKI setup failed\n");
1070 return ret;
1071 }
1072 if (m_context->setup_data.validate_sni_call_back) {
1073 mbedtls_ssl_conf_sni(&m_env->conf, pki_sni_callback, c_session);
1074 }
1075 }
1076
1077 if ((ret = mbedtls_ssl_cookie_setup(&m_env->cookie_ctx,
1078 mbedtls_ctr_drbg_random,
1079 &m_env->ctr_drbg)) != 0) {
1080 coap_log_err("mbedtls_ssl_cookie_setup: returned -0x%x: '%s'\n",
1081 -ret, get_error_string(ret));
1082 goto fail;
1083 }
1084
1085#if defined(MBEDTLS_SSL_PROTO_DTLS)
1086 mbedtls_ssl_conf_dtls_cookies(&m_env->conf, mbedtls_ssl_cookie_write,
1087 mbedtls_ssl_cookie_check,
1088 &m_env->cookie_ctx);
1089#if MBEDTLS_VERSION_NUMBER >= 0x02100100
1090 mbedtls_ssl_set_mtu(&m_env->ssl, (uint16_t)c_session->mtu);
1091#endif /* MBEDTLS_VERSION_NUMBER >= 0x02100100 */
1092#endif /* MBEDTLS_SSL_PROTO_DTLS */
1093#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
1094 /*
1095 * Configure CID max length.
1096 *
1097 * Note: Set MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT to 0 (the default)
1098 * to use RFC9146 extension ID of 54, rather than the draft version -05
1099 * value of 254.
1100 */
1101 mbedtls_ssl_conf_cid(&m_env->conf, COAP_DTLS_CID_LENGTH, MBEDTLS_SSL_UNEXPECTED_CID_IGNORE);
1102#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1103fail:
1104 return ret;
1105}
1106#endif /* MBEDTLS_SSL_SRV_C */
1107
1108#if COAP_CLIENT_SUPPORT
1109static int *psk_ciphers = NULL;
1110static int *pki_ciphers = NULL;
1111static int *ecjpake_ciphers = NULL;
1112static int processed_ciphers = 0;
1113
1114#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1115static int
1116coap_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info) {
1117#if MBEDTLS_VERSION_NUMBER >= 0x03060000
1118 switch (info->key_exchange) {
1119 case MBEDTLS_KEY_EXCHANGE_PSK:
1120 case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
1121 case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
1122 case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
1123 return 1;
1124 case MBEDTLS_KEY_EXCHANGE_NONE:
1125 case MBEDTLS_KEY_EXCHANGE_RSA:
1126 case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
1127 case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
1128 case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
1129 case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
1130 case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
1131 case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
1132 default:
1133 return 0;
1134 }
1135#else /* MBEDTLS_VERSION_NUMBER < 0x03060000 */
1136 return mbedtls_ssl_ciphersuite_uses_psk(info);
1137#endif /* MBEDTLS_VERSION_NUMBER < 0x03060000 */
1138}
1139#endif /* defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) */
1140
1141static void
1142set_ciphersuites(mbedtls_ssl_config *conf, coap_enc_method_t method) {
1143 if (!processed_ciphers) {
1144 const int *list = mbedtls_ssl_list_ciphersuites();
1145 const int *base = list;
1146 int *psk_list;
1147 int *pki_list;
1148#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1149 int *ecjpake_list;
1150 int ecjpake_count = 1;
1151#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1152 int psk_count = 1; /* account for empty terminator */
1153 int pki_count = 1;
1154
1155 while (*list) {
1156 const mbedtls_ssl_ciphersuite_t *cur =
1157 mbedtls_ssl_ciphersuite_from_id(*list);
1158
1159 if (cur) {
1160#if MBEDTLS_VERSION_NUMBER >= 0x03020000
1161 if (cur->max_tls_version < MBEDTLS_SSL_VERSION_TLS1_2) {
1162 /* Minimum of TLS1.2 required - skip */
1163 }
1164#else
1165 if (cur->max_minor_ver < MBEDTLS_SSL_MINOR_VERSION_3) {
1166 /* Minimum of TLS1.2 required - skip */
1167 }
1168#endif /* MBEDTLS_VERSION_NUMBER >= 0x03020000 */
1169#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1170 else if (cur->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
1171 ecjpake_count++;
1172 }
1173#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1174#if MBEDTLS_VERSION_NUMBER >= 0x03060000
1175 else if (cur->min_tls_version >= MBEDTLS_SSL_VERSION_TLS1_3) {
1176 psk_count++;
1177 pki_count++;
1178 }
1179#endif /* MBEDTLS_VERSION_NUMBER >= 0x03060000 */
1180#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1181 else if (coap_ssl_ciphersuite_uses_psk(cur)) {
1182 psk_count++;
1183 }
1184#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
1185 else {
1186 pki_count++;
1187 }
1188 }
1189 list++;
1190 }
1191 list = base;
1192
1193 psk_ciphers = mbedtls_malloc(psk_count * sizeof(psk_ciphers[0]));
1194 if (psk_ciphers == NULL) {
1195 coap_log_err("set_ciphers: mbedtls_malloc with count %d failed\n", psk_count);
1196 return;
1197 }
1198 pki_ciphers = mbedtls_malloc(pki_count * sizeof(pki_ciphers[0]));
1199 if (pki_ciphers == NULL) {
1200 coap_log_err("set_ciphers: mbedtls_malloc with count %d failed\n", pki_count);
1201 mbedtls_free(psk_ciphers);
1202 psk_ciphers = NULL;
1203 return;
1204 }
1205#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1206 ecjpake_ciphers = mbedtls_malloc(ecjpake_count * sizeof(ecjpake_ciphers[0]));
1207 if (ecjpake_ciphers == NULL) {
1208 coap_log_err("set_ciphers: mbedtls_malloc with count %d failed\n", pki_count);
1209 mbedtls_free(psk_ciphers);
1210 mbedtls_free(pki_ciphers);
1211 psk_ciphers = NULL;
1212 pki_ciphers = NULL;
1213 return;
1214 }
1215#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1216
1217 psk_list = psk_ciphers;
1218 pki_list = pki_ciphers;
1219#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1220 ecjpake_list = ecjpake_ciphers;
1221#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1222
1223 while (*list) {
1224 const mbedtls_ssl_ciphersuite_t *cur =
1225 mbedtls_ssl_ciphersuite_from_id(*list);
1226 if (cur) {
1227#if MBEDTLS_VERSION_NUMBER >= 0x03020000
1228 if (cur->max_tls_version < MBEDTLS_SSL_VERSION_TLS1_2) {
1229 /* Minimum of TLS1.2 required - skip */
1230 }
1231#else
1232 if (cur->max_minor_ver < MBEDTLS_SSL_MINOR_VERSION_3) {
1233 /* Minimum of TLS1.2 required - skip */
1234 }
1235#endif /* MBEDTLS_VERSION_NUMBER >= 0x03020000 */
1236#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1237 else if (cur->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
1238 *ecjpake_list = *list;
1239 ecjpake_list++;
1240 }
1241#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1242#if MBEDTLS_VERSION_NUMBER >= 0x03060000
1243 else if (cur->min_tls_version >= MBEDTLS_SSL_VERSION_TLS1_3) {
1244 *psk_list = *list;
1245 psk_list++;
1246 *pki_list = *list;
1247 pki_list++;
1248 }
1249#endif /* MBEDTLS_VERSION_NUMBER >= 0x03060000 */
1250#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1251 else if (coap_ssl_ciphersuite_uses_psk(cur)) {
1252 *psk_list = *list;
1253 psk_list++;
1254 }
1255#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
1256 else {
1257 *pki_list = *list;
1258 pki_list++;
1259 }
1260 }
1261 list++;
1262 }
1263 /* zero terminate */
1264 *psk_list = 0;
1265 *pki_list = 0;
1266 processed_ciphers = 1;
1267 }
1268 switch (method) {
1269 case COAP_ENC_PSK:
1270 mbedtls_ssl_conf_ciphersuites(conf, psk_ciphers);
1271 break;
1272 case COAP_ENC_PKI:
1273 mbedtls_ssl_conf_ciphersuites(conf, pki_ciphers);
1274 break;
1275 case COAP_ENC_ECJPAKE:
1276 mbedtls_ssl_conf_ciphersuites(conf, ecjpake_ciphers);
1277 break;
1278 default:
1279 assert(0);
1280 break;
1281 }
1282}
1283
1284static int
1285setup_client_ssl_session(coap_session_t *c_session,
1286 coap_mbedtls_env_t *m_env) {
1287 int ret;
1288
1289 coap_mbedtls_context_t *m_context =
1290 (coap_mbedtls_context_t *)c_session->context->dtls_context;
1291
1292 m_context->psk_pki_enabled |= IS_CLIENT;
1293
1294 if ((ret = mbedtls_ssl_config_defaults(&m_env->conf,
1295 MBEDTLS_SSL_IS_CLIENT,
1296 c_session->proto == COAP_PROTO_DTLS ?
1297 MBEDTLS_SSL_TRANSPORT_DATAGRAM :
1298 MBEDTLS_SSL_TRANSPORT_STREAM,
1299 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
1300 coap_log_err("mbedtls_ssl_config_defaults returned -0x%x: '%s'\n",
1301 -ret, get_error_string(ret));
1302 goto fail;
1303 }
1304
1305#if defined(MBEDTLS_SSL_PROTO_DTLS)
1306 mbedtls_ssl_conf_handshake_timeout(&m_env->conf, COAP_DTLS_RETRANSMIT_MS,
1307 COAP_DTLS_RETRANSMIT_TOTAL_MS);
1308#endif /* MBEDTLS_SSL_PROTO_DTLS */
1309
1310 mbedtls_ssl_conf_authmode(&m_env->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
1311 mbedtls_ssl_conf_rng(&m_env->conf, mbedtls_ctr_drbg_random, &m_env->ctr_drbg);
1312
1313 if (m_context->psk_pki_enabled & IS_PSK) {
1314#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1315 const coap_bin_const_t *psk_key;
1316 const coap_bin_const_t *psk_identity;
1317
1318 coap_log_info("Setting PSK key\n");
1319
1320 psk_key = coap_get_session_client_psk_key(c_session);
1321 psk_identity = coap_get_session_client_psk_identity(c_session);
1322 if (psk_key == NULL || psk_identity == NULL) {
1323 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
1324 goto fail;
1325 }
1326
1327 if ((ret = mbedtls_ssl_conf_psk(&m_env->conf, psk_key->s,
1328 psk_key->length, psk_identity->s,
1329 psk_identity->length)) != 0) {
1330 coap_log_err("mbedtls_ssl_conf_psk returned -0x%x: '%s'\n",
1331 -ret, get_error_string(ret));
1332 goto fail;
1333 }
1334 if (c_session->cpsk_setup_data.client_sni) {
1335 if ((ret = mbedtls_ssl_set_hostname(&m_env->ssl,
1336 c_session->cpsk_setup_data.client_sni)) != 0) {
1337 coap_log_err("mbedtls_ssl_set_hostname returned -0x%x: '%s'\n",
1338 -ret, get_error_string(ret));
1339 goto fail;
1340 }
1341 }
1342 /* Identity Hint currently not supported in Mbed TLS so code removed */
1343
1344#ifdef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
1345 if (c_session->cpsk_setup_data.ec_jpake) {
1346 m_env->ec_jpake = 1;
1347 set_ciphersuites(&m_env->conf, COAP_ENC_ECJPAKE);
1348#if MBEDTLS_VERSION_NUMBER >= 0x03020000
1349 mbedtls_ssl_conf_max_tls_version(&m_env->conf, MBEDTLS_SSL_VERSION_TLS1_2);
1350#endif /* MBEDTLS_VERSION_NUMBER >= 0x03020000 */
1351 } else {
1352 set_ciphersuites(&m_env->conf, COAP_ENC_PSK);
1353 }
1354#else /* ! MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1355 set_ciphersuites(&m_env->conf, COAP_ENC_PSK);
1356#endif /* ! MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1357#else /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
1358 coap_log_warn("PSK not enabled in Mbed TLS library\n");
1359#endif /* ! MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
1360 } else if ((m_context->psk_pki_enabled & IS_PKI) ||
1361 (m_context->psk_pki_enabled & (IS_PSK | IS_PKI)) == 0) {
1362 /*
1363 * If neither PSK or PKI have been set up, use PKI basics.
1364 * This works providing COAP_PKI_KEY_PEM has a value of 0.
1365 */
1366 mbedtls_ssl_conf_authmode(&m_env->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
1367 ret = setup_pki_credentials(&m_env->cacert, &m_env->public_cert,
1368 &m_env->private_key, m_env, m_context,
1369 c_session, &m_context->setup_data,
1371 if (ret < 0) {
1372 coap_log_err("PKI setup failed\n");
1373 return ret;
1374 }
1375#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_ALPN)
1376 if (c_session->proto == COAP_PROTO_TLS ||
1377 c_session->proto == COAP_PROTO_WSS) {
1378 static const char *alpn_list[] = { "coap", NULL };
1379
1380 ret = mbedtls_ssl_conf_alpn_protocols(&m_env->conf, alpn_list);
1381 if (ret != 0) {
1382 coap_log_err("ALPN setup failed %d)\n", ret);
1383 }
1384 }
1385#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_ALPN */
1386 if (m_context->setup_data.client_sni) {
1387 mbedtls_ssl_set_hostname(&m_env->ssl, m_context->setup_data.client_sni);
1388 }
1389#if defined(MBEDTLS_SSL_PROTO_DTLS)
1390#if MBEDTLS_VERSION_NUMBER >= 0x02100100
1391 mbedtls_ssl_set_mtu(&m_env->ssl, (uint16_t)c_session->mtu);
1392#endif /* MBEDTLS_VERSION_NUMBER >= 0x02100100 */
1393#endif /* MBEDTLS_SSL_PROTO_DTLS */
1394 set_ciphersuites(&m_env->conf, COAP_ENC_PKI);
1395 }
1396 return 0;
1397
1398fail:
1399 return ret;
1400}
1401#endif /* COAP_CLIENT_SUPPORT */
1402
1403static void
1404mbedtls_cleanup(coap_mbedtls_env_t *m_env) {
1405 if (!m_env) {
1406 return;
1407 }
1408
1409 mbedtls_x509_crt_free(&m_env->cacert);
1410 mbedtls_x509_crt_free(&m_env->public_cert);
1411 mbedtls_pk_free(&m_env->private_key);
1412 mbedtls_entropy_free(&m_env->entropy);
1413 mbedtls_ssl_config_free(&m_env->conf);
1414 mbedtls_ctr_drbg_free(&m_env->ctr_drbg);
1415 mbedtls_ssl_free(&m_env->ssl);
1416 mbedtls_ssl_cookie_free(&m_env->cookie_ctx);
1417}
1418
1419static void
1420coap_dtls_free_mbedtls_env(coap_mbedtls_env_t *m_env) {
1421 if (m_env) {
1422 if (!m_env->sent_alert)
1423 mbedtls_ssl_close_notify(&m_env->ssl);
1424 mbedtls_cleanup(m_env);
1425 mbedtls_free(m_env);
1426 }
1427}
1428
1429#if COAP_MAX_LOGGING_LEVEL > 0
1430static const char *
1431report_mbedtls_alert(unsigned char alert) {
1432 switch (alert) {
1433 case MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC:
1434 return ": Bad Record MAC";
1435 case MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE:
1436 return ": Handshake failure";
1437 case MBEDTLS_SSL_ALERT_MSG_NO_CERT:
1438 return ": No Certificate provided";
1439 case MBEDTLS_SSL_ALERT_MSG_BAD_CERT:
1440 return ": Certificate is bad";
1441 case MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN:
1442 return ": Certificate is unknown";
1443 case MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA:
1444 return ": CA is unknown";
1445 case MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED:
1446 return ": Access was denied";
1447 case MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR:
1448 return ": Decrypt error";
1449 default:
1450 return "";
1451 }
1452}
1453#endif /* COAP_MAX_LOGGING_LEVEL */
1454
1455/*
1456 * return -1 failure
1457 * 0 not completed
1458 * 1 established
1459 */
1460static int
1461do_mbedtls_handshake(coap_session_t *c_session,
1462 coap_mbedtls_env_t *m_env) {
1463 int ret;
1464 int alert;
1465
1466 ret = mbedtls_ssl_handshake(&m_env->ssl);
1467 switch (ret) {
1468 case 0:
1469 m_env->established = 1;
1470 coap_log_debug("* %s: Mbed TLS established\n",
1471 coap_session_str(c_session));
1472 ret = 1;
1473#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
1474#if COAP_CLIENT_SUPPORT
1475 if (c_session->type == COAP_SESSION_TYPE_CLIENT &&
1476 c_session->proto == COAP_PROTO_DTLS) {
1477 coap_mbedtls_context_t *m_context;
1478
1479 m_context = (coap_mbedtls_context_t *)c_session->context->dtls_context;
1480 if ((m_context->psk_pki_enabled & IS_PSK && c_session->cpsk_setup_data.use_cid) ||
1481 m_context->setup_data.use_cid) {
1482 unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX];
1483 int enabled;
1484 size_t peer_cid_len;
1485
1486 /* See whether CID was negotiated */
1487 if (mbedtls_ssl_get_peer_cid(&m_env->ssl, &enabled, peer_cid, &peer_cid_len) == 0 &&
1488 enabled == MBEDTLS_SSL_CID_ENABLED) {
1489 c_session->negotiated_cid = 1;
1490 } else {
1491 coap_log_info("** %s: CID was not negotiated\n", coap_session_str(c_session));
1492 c_session->negotiated_cid = 0;
1493 }
1494 }
1495 }
1496#endif /* COAP_CLIENT_SUPPORT */
1497#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1498 break;
1499 case MBEDTLS_ERR_SSL_WANT_READ:
1500 case MBEDTLS_ERR_SSL_WANT_WRITE:
1501 if (m_env->ssl.state == MBEDTLS_SSL_SERVER_HELLO
1502#if MBEDTLS_VERSION_NUMBER >= 0x03030000
1503 || m_env->ssl.state == MBEDTLS_SSL_NEW_SESSION_TICKET
1504#endif /* MBEDTLS_VERSION_NUMBER >= 0x03030000 */
1505 ) {
1506 if (++m_env->server_hello_cnt > 10) {
1507 /* retried this too many times */
1508 goto fail;
1509 }
1510 }
1511 errno = EAGAIN;
1512 ret = 0;
1513 break;
1514 case MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED:
1515 coap_log_debug("hello verification requested\n");
1516 goto reset;
1517 case MBEDTLS_ERR_SSL_INVALID_MAC:
1518 goto fail;
1519#ifdef MBEDTLS_2_X_COMPAT
1520 case MBEDTLS_ERR_SSL_UNKNOWN_CIPHER:
1521#else /* ! MBEDTLS_2_X_COMPAT */
1522 case MBEDTLS_ERR_SSL_DECODE_ERROR:
1523#endif /* ! MBEDTLS_2_X_COMPAT */
1524 goto fail;
1525 case MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE:
1526 alert = MBEDTLS_SSL_ALERT_MSG_NO_CERT;
1527 goto fail_alert;
1528#ifdef MBEDTLS_2_X_COMPAT
1529 case MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO:
1530 case MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO:
1531 alert = MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE;
1532 goto fail_alert;
1533#endif /* MBEDTLS_2_X_COMPAT */
1534 case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:
1535 goto fail;
1536 case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
1537 if (m_env->ssl.in_msg[1] != MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY)
1538 coap_log_warn("***%s: Alert '%d'%s\n",
1539 coap_session_str(c_session), m_env->ssl.in_msg[1],
1540 report_mbedtls_alert(m_env->ssl.in_msg[1]));
1541 /* Fall through */
1542 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
1543 case MBEDTLS_ERR_SSL_CONN_EOF:
1544 case MBEDTLS_ERR_NET_CONN_RESET:
1546 ret = -1;
1547 break;
1548 default:
1549 coap_log_warn("do_mbedtls_handshake: session establish "
1550 "returned -0x%x: '%s'\n",
1551 -ret, get_error_string(ret));
1552 ret = -1;
1553 break;
1554 }
1555 return ret;
1556
1557fail_alert:
1558 mbedtls_ssl_send_alert_message(&m_env->ssl,
1559 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1560 alert);
1561 m_env->sent_alert = 1;
1562fail:
1563 c_session->dtls_event = COAP_EVENT_DTLS_ERROR;
1564 coap_log_warn("do_mbedtls_handshake: session establish "
1565 "returned '%s'\n",
1566 get_error_string(ret));
1567reset:
1568 mbedtls_ssl_session_reset(&m_env->ssl);
1569#ifdef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
1570 if (m_env->ec_jpake) {
1571 const coap_bin_const_t *psk_key;
1572
1573#if COAP_CLIENT_SUPPORT && COAP_SERVER_SUPPORT
1574 if (c_session->type == COAP_SESSION_TYPE_CLIENT) {
1575 psk_key = coap_get_session_client_psk_key(c_session);
1576 } else {
1577 psk_key = coap_get_session_server_psk_key(c_session);
1578 }
1579#elif COAP_CLIENT_SUPPORT
1580 psk_key = coap_get_session_client_psk_key(c_session);
1581#else /* COAP_SERVER_SUPPORT */
1582 psk_key = coap_get_session_server_psk_key(c_session);
1583#endif /* COAP_SERVER_SUPPORT */
1584 if (psk_key) {
1585 mbedtls_ssl_set_hs_ecjpake_password(&m_env->ssl, psk_key->s, psk_key->length);
1586 }
1587 }
1588#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1589 return -1;
1590}
1591
1592static void
1593mbedtls_debug_out(void *ctx COAP_UNUSED, int level,
1594 const char *file COAP_UNUSED,
1595 int line COAP_UNUSED, const char *str) {
1596
1597 coap_log_t coap_level = COAP_LOG_DEBUG;
1598 /*
1599 * 0 No debug
1600 * 1 Error
1601 * 2 State change
1602 * 3 Informational
1603 * 4 Verbose
1604 */
1605 switch (level) {
1606 case 0:
1607 coap_level = COAP_LOG_EMERG;
1608 break;
1609 case 1:
1610 coap_level = COAP_LOG_WARN;
1611 break;
1612 case 2:
1613 coap_level = COAP_LOG_NOTICE;
1614 break;
1615 case 3:
1616 coap_level = COAP_LOG_INFO;
1617 break;
1618 case 4:
1619 default:
1620 coap_level = COAP_LOG_DEBUG;
1621 break;
1622 }
1623 coap_dtls_log(coap_level, "%s", str);
1624}
1625
1626#if !COAP_DISABLE_TCP
1627/*
1628 * strm
1629 * return +ve data amount
1630 * 0 no more
1631 * -ve Mbed TLS error
1632 */
1633static int
1634coap_sock_read(void *ctx, unsigned char *out, size_t outl) {
1635 int ret = MBEDTLS_ERR_SSL_CONN_EOF;
1636 coap_session_t *c_session = (coap_session_t *)ctx;
1637
1638 if (out != NULL) {
1639 ret = (int)c_session->sock.lfunc[COAP_LAYER_TLS].l_read(c_session, out, outl);
1640 /* Translate layer returns into what MbedTLS expects */
1641 if (ret == -1) {
1642 if (errno == ECONNRESET) {
1643 /* graceful shutdown */
1644 ret = MBEDTLS_ERR_SSL_CONN_EOF;
1645 } else {
1646 ret = MBEDTLS_ERR_NET_RECV_FAILED;
1647 }
1648 } else if (ret == 0) {
1649 errno = EAGAIN;
1650 ret = MBEDTLS_ERR_SSL_WANT_READ;
1651 }
1652 }
1653 return ret;
1654}
1655
1656/*
1657 * strm
1658 * return +ve data amount
1659 * 0 no more
1660 * -ve Mbed TLS error
1661 */
1662static int
1663coap_sock_write(void *context, const unsigned char *in, size_t inl) {
1664 int ret = 0;
1665 coap_session_t *c_session = (coap_session_t *)context;
1666
1667 ret = c_session->sock.lfunc[COAP_LAYER_TLS].l_write(c_session,
1668 (const uint8_t *)in,
1669 inl);
1670 /* Translate layer what returns into what MbedTLS expects */
1671 if (ret < 0) {
1672 if ((c_session->state == COAP_SESSION_STATE_CSM ||
1673 c_session->state == COAP_SESSION_STATE_HANDSHAKE) &&
1674 (errno == EPIPE || errno == ECONNRESET)) {
1675 /*
1676 * Need to handle a TCP timing window where an agent continues with
1677 * the sending of the next handshake or a CSM.
1678 * However, the peer does not like a certificate and so sends a
1679 * fatal alert and closes the TCP session.
1680 * The sending of the next handshake or CSM may get terminated because
1681 * of the closed TCP session, but there is still an outstanding alert
1682 * to be read in and reported on.
1683 * In this case, pretend that sending the info was fine so that the
1684 * alert can be read (which effectively is what happens with DTLS).
1685 */
1686 ret = inl;
1687 } else {
1688#ifdef _WIN32
1689 int lasterror = WSAGetLastError();
1690
1691 if (lasterror == WSAEWOULDBLOCK) {
1692 ret = MBEDTLS_ERR_SSL_WANT_WRITE;
1693 } else if (lasterror == WSAECONNRESET) {
1694 ret = MBEDTLS_ERR_NET_CONN_RESET;
1695 }
1696#else
1697 if (errno == EAGAIN || errno == EINTR) {
1698 ret = MBEDTLS_ERR_SSL_WANT_WRITE;
1699 } else if (errno == EPIPE || errno == ECONNRESET) {
1700 ret = MBEDTLS_ERR_NET_CONN_RESET;
1701 }
1702#endif
1703 else {
1704 ret = MBEDTLS_ERR_NET_SEND_FAILED;
1705 }
1706 coap_log_debug("* %s: failed to send %zd bytes (%s) state %d\n",
1707 coap_session_str(c_session), inl, coap_socket_strerror(),
1708 c_session->state);
1709 }
1710 }
1711 if (ret == 0) {
1712 errno = EAGAIN;
1713 ret = MBEDTLS_ERR_SSL_WANT_WRITE;
1714 }
1715 return ret;
1716}
1717#endif /* !COAP_DISABLE_TCP */
1718
1719static coap_mbedtls_env_t *
1720coap_dtls_new_mbedtls_env(coap_session_t *c_session,
1721 coap_dtls_role_t role,
1722 coap_proto_t proto) {
1723 int ret = 0;
1724 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
1725
1726 if (m_env)
1727 return m_env;
1728
1729 m_env = (coap_mbedtls_env_t *)mbedtls_malloc(sizeof(coap_mbedtls_env_t));
1730 if (!m_env) {
1731 return NULL;
1732 }
1733 memset(m_env, 0, sizeof(coap_mbedtls_env_t));
1734
1735 mbedtls_ssl_init(&m_env->ssl);
1736 mbedtls_ctr_drbg_init(&m_env->ctr_drbg);
1737 mbedtls_ssl_config_init(&m_env->conf);
1738 mbedtls_entropy_init(&m_env->entropy);
1739
1740#if defined(MBEDTLS_PSA_CRYPTO_C)
1741 psa_crypto_init();
1742#endif /* MBEDTLS_PSA_CRYPTO_C */
1743
1744#if defined(ESPIDF_VERSION) && defined(CONFIG_MBEDTLS_DEBUG)
1745 mbedtls_esp_enable_debug_log(&m_env->conf, CONFIG_MBEDTLS_DEBUG_LEVEL);
1746#endif /* ESPIDF_VERSION && CONFIG_MBEDTLS_DEBUG */
1747 if ((ret = mbedtls_ctr_drbg_seed(&m_env->ctr_drbg,
1748 mbedtls_entropy_func, &m_env->entropy, NULL, 0)) != 0) {
1749 if (ret != MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) {
1750 coap_log_info("mbedtls_ctr_drbg_seed returned -0x%x: '%s'\n",
1751 -ret, get_error_string(ret));
1752 goto fail;
1753 }
1754 coap_log_err("mbedtls_ctr_drbg_seed returned -0x%x: '%s'\n",
1755 -ret, get_error_string(ret));
1756 }
1757
1758 if (role == COAP_DTLS_ROLE_CLIENT) {
1759#if COAP_CLIENT_SUPPORT
1760 if (setup_client_ssl_session(c_session, m_env) != 0) {
1761 goto fail;
1762 }
1763#else /* !COAP_CLIENT_SUPPORT */
1764 goto fail;
1765#endif /* !COAP_CLIENT_SUPPORT */
1766 } else if (role == COAP_DTLS_ROLE_SERVER) {
1767#if defined(MBEDTLS_SSL_SRV_C)
1768 if (setup_server_ssl_session(c_session, m_env) != 0) {
1769 goto fail;
1770 }
1771#else /* ! MBEDTLS_SSL_SRV_C */
1772 goto fail;
1773#endif /* ! MBEDTLS_SSL_SRV_C */
1774 } else {
1775 goto fail;
1776 }
1777
1778#if MBEDTLS_VERSION_NUMBER >= 0x03020000
1779 mbedtls_ssl_conf_min_tls_version(&m_env->conf, MBEDTLS_SSL_VERSION_TLS1_2);
1780#else
1781 mbedtls_ssl_conf_min_version(&m_env->conf, MBEDTLS_SSL_MAJOR_VERSION_3,
1782 MBEDTLS_SSL_MINOR_VERSION_3);
1783#endif /* MBEDTLS_VERSION_NUMBER >= 0x03020000 */
1784
1785 if (mbedtls_ssl_setup(&m_env->ssl, &m_env->conf) != 0) {
1786 goto fail;
1787 }
1788 if (proto == COAP_PROTO_DTLS) {
1789 mbedtls_ssl_set_bio(&m_env->ssl, c_session, coap_dgram_write,
1790 coap_dgram_read, NULL);
1791#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
1792 if (COAP_PROTO_NOT_RELIABLE(c_session->proto)) {
1793 if (role == COAP_DTLS_ROLE_CLIENT) {
1794#if COAP_CLIENT_SUPPORT
1795 coap_mbedtls_context_t *m_context =
1796 (coap_mbedtls_context_t *)c_session->context->dtls_context;
1797
1798 if ((m_context->psk_pki_enabled & IS_PSK && c_session->cpsk_setup_data.use_cid) ||
1799 m_context->setup_data.use_cid) {
1800 /*
1801 * Enable passive DTLS CID support.
1802 *
1803 * Note: Set MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT to 0 (the default)
1804 * to use RFC9146 extension ID of 54, rather than the draft version -05
1805 * value of 254.
1806 */
1807 mbedtls_ssl_set_cid(&m_env->ssl, MBEDTLS_SSL_CID_ENABLED, NULL, 0);
1808 }
1809#endif /* COAP_CLIENT_SUPPORT */
1810 } else {
1811#if COAP_SERVER_SUPPORT
1812 u_char cid[COAP_DTLS_CID_LENGTH];
1813 /*
1814 * Enable server DTLS CID support.
1815 *
1816 * Note: Set MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT to 0 (the default)
1817 * to use RFC9146 extension ID of 54, rather than the draft version -05
1818 * value of 254.
1819 */
1820 coap_prng_lkd(cid, sizeof(cid));
1821 mbedtls_ssl_set_cid(&m_env->ssl, MBEDTLS_SSL_CID_ENABLED, cid,
1822 sizeof(cid));
1823 c_session->client_cid = coap_new_bin_const(cid, sizeof(cid));
1824#endif /* COAP_SERVER_SUPPORT */
1825 }
1826 }
1827#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1828 }
1829#if !COAP_DISABLE_TCP
1830 else {
1831 assert(proto == COAP_PROTO_TLS);
1832 mbedtls_ssl_set_bio(&m_env->ssl, c_session, coap_sock_write,
1833 coap_sock_read, NULL);
1834 }
1835#endif /* ! COAP_DISABLE_TCP */
1836#ifdef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
1837 coap_mbedtls_context_t *m_context =
1838 ((coap_mbedtls_context_t *)c_session->context->dtls_context);
1839 if ((m_context->psk_pki_enabled & IS_PSK) &&
1840 m_env->ec_jpake) {
1841 const coap_bin_const_t *psk_key;
1842
1843#if COAP_CLIENT_SUPPORT && COAP_SERVER_SUPPORT
1844 if (role == COAP_DTLS_ROLE_CLIENT) {
1845 psk_key = coap_get_session_client_psk_key(c_session);
1846 } else {
1847 psk_key = coap_get_session_server_psk_key(c_session);
1848 }
1849#elif COAP_CLIENT_SUPPORT
1850 psk_key = coap_get_session_client_psk_key(c_session);
1851#else /* COAP_SERVER_SUPPORT */
1852 psk_key = coap_get_session_server_psk_key(c_session);
1853#endif /* COAP_SERVER_SUPPORT */
1854 mbedtls_ssl_set_hs_ecjpake_password(&m_env->ssl, psk_key->s, psk_key->length);
1855 }
1856#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1857 mbedtls_ssl_set_timer_cb(&m_env->ssl, &m_env->timer,
1858 mbedtls_timing_set_delay,
1859 mbedtls_timing_get_delay);
1860
1861 mbedtls_ssl_conf_dbg(&m_env->conf, mbedtls_debug_out, stdout);
1862 return m_env;
1863
1864fail:
1865 if (m_env) {
1866 mbedtls_free(m_env);
1867 }
1868 return NULL;
1869}
1870
1871int
1873#if defined(MBEDTLS_SSL_PROTO_DTLS)
1874 return 1;
1875#else /* !MBEDTLS_SSL_PROTO_DTLS */
1876 static int reported = 0;
1877 if (!reported) {
1878 reported = 1;
1879 coap_log_emerg("libcoap not compiled for DTLS with Mbed TLS"
1880 " - update Mbed TLS to include DTLS\n");
1881 }
1882 return 0;
1883#endif /* !MBEDTLS_SSL_PROTO_DTLS */
1884}
1885
1886int
1888#if !COAP_DISABLE_TCP
1889 return 1;
1890#else /* COAP_DISABLE_TCP */
1891 return 0;
1892#endif /* COAP_DISABLE_TCP */
1893}
1894
1895/*
1896 * return 0 failed
1897 * 1 passed
1898 */
1899int
1901 return 1;
1902}
1903
1904/*
1905 * return 0 failed
1906 * 1 passed
1907 */
1908int
1910 return 1;
1911}
1912
1913/*
1914 * return 0 failed
1915 * 1 passed
1916 */
1917int
1919 return 0;
1920}
1921
1922/*
1923 * return 0 failed
1924 * 1 passed
1925 */
1926int
1928 return 0;
1929}
1930
1931/*
1932 * return 0 failed
1933 * 1 passed
1934 */
1935int
1937#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
1938 return 1;
1939#else /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
1940 return 0;
1941#endif /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
1942}
1943
1944#if COAP_CLIENT_SUPPORT
1945int
1946coap_dtls_set_cid_tuple_change(coap_context_t *c_context, uint8_t every) {
1947#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
1948 c_context->testing_cids = every;
1949 return 1;
1950#else /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
1951 (void)c_context;
1952 (void)every;
1953 return 0;
1954#endif /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
1955}
1956#endif /* COAP_CLIENT_SUPPORT */
1957
1958void *
1960 coap_mbedtls_context_t *m_context;
1961 (void)c_context;
1962
1963 m_context = (coap_mbedtls_context_t *)mbedtls_malloc(sizeof(coap_mbedtls_context_t));
1964 if (m_context) {
1965 memset(m_context, 0, sizeof(coap_mbedtls_context_t));
1966 }
1967 return m_context;
1968}
1969
1970#if COAP_SERVER_SUPPORT
1971/*
1972 * return 0 failed
1973 * 1 passed
1974 */
1975int
1977 coap_dtls_spsk_t *setup_data
1978 ) {
1979 coap_mbedtls_context_t *m_context =
1980 ((coap_mbedtls_context_t *)c_context->dtls_context);
1981
1982#if !defined(MBEDTLS_SSL_SRV_C)
1983 coap_log_emerg("coap_context_set_spsk:"
1984 " libcoap not compiled for Server Mode for Mbed TLS"
1985 " - update Mbed TLS to include Server Mode\n");
1986 return 0;
1987#endif /* !MBEDTLS_SSL_SRV_C */
1988 if (!m_context || !setup_data)
1989 return 0;
1990
1991 if (setup_data->ec_jpake) {
1992#ifndef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
1993 coap_log_warn("Mbed TLS not compiled for EC-JPAKE support\n");
1994#endif /* ! MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1995 }
1996 m_context->psk_pki_enabled |= IS_PSK;
1997 return 1;
1998}
1999#endif /* COAP_SERVER_SUPPORT */
2000
2001#if COAP_CLIENT_SUPPORT
2002/*
2003 * return 0 failed
2004 * 1 passed
2005 */
2006int
2008 coap_dtls_cpsk_t *setup_data
2009 ) {
2010#if !defined(MBEDTLS_SSL_CLI_C)
2011 (void)c_context;
2012 (void)setup_data;
2013
2014 coap_log_emerg("coap_context_set_cpsk:"
2015 " libcoap not compiled for Client Mode for Mbed TLS"
2016 " - update Mbed TLS to include Client Mode\n");
2017 return 0;
2018#else /* MBEDTLS_SSL_CLI_C */
2019 coap_mbedtls_context_t *m_context =
2020 ((coap_mbedtls_context_t *)c_context->dtls_context);
2021
2022 if (!m_context || !setup_data)
2023 return 0;
2024
2025 if (setup_data->validate_ih_call_back) {
2026 coap_log_warn("CoAP Client with Mbed TLS does not support Identity Hint selection\n");
2027 }
2028 if (setup_data->ec_jpake) {
2029#ifndef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
2030 coap_log_warn("Mbed TLS not compiled for EC-JPAKE support\n");
2031#endif /* ! MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
2032 }
2033 if (setup_data->use_cid) {
2034#ifndef MBEDTLS_SSL_DTLS_CONNECTION_ID
2035 coap_log_warn("Mbed TLS not compiled for Connection-ID support\n");
2036#endif /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
2037 }
2038 m_context->psk_pki_enabled |= IS_PSK;
2039 return 1;
2040#endif /* MBEDTLS_SSL_CLI_C */
2041}
2042#endif /* COAP_CLIENT_SUPPORT */
2043
2044int
2046 const coap_dtls_pki_t *setup_data,
2047 const coap_dtls_role_t role COAP_UNUSED) {
2048 coap_mbedtls_context_t *m_context =
2049 ((coap_mbedtls_context_t *)c_context->dtls_context);
2050
2051 m_context->setup_data = *setup_data;
2052 if (!m_context->setup_data.verify_peer_cert) {
2053 /* Needs to be clear so that no CA DNs are transmitted */
2054 m_context->setup_data.check_common_ca = 0;
2055 /* Allow all of these but warn if issue */
2056 m_context->setup_data.allow_self_signed = 1;
2057 m_context->setup_data.allow_expired_certs = 1;
2058 m_context->setup_data.cert_chain_validation = 1;
2059 m_context->setup_data.cert_chain_verify_depth = 10;
2060 m_context->setup_data.check_cert_revocation = 1;
2061 m_context->setup_data.allow_no_crl = 1;
2062 m_context->setup_data.allow_expired_crl = 1;
2063 m_context->setup_data.allow_bad_md_hash = 1;
2064 m_context->setup_data.allow_short_rsa_length = 1;
2065 }
2066 m_context->psk_pki_enabled |= IS_PKI;
2067 if (setup_data->use_cid) {
2068#ifndef MBEDTLS_SSL_DTLS_CONNECTION_ID
2069 coap_log_warn("Mbed TLS not compiled for Connection-ID support\n");
2070#endif /* ! MBEDTLS_SSL_DTLS_CONNECTION_ID */
2071 }
2072 return 1;
2073}
2074
2075int
2077 const char *ca_file,
2078 const char *ca_path) {
2079 coap_mbedtls_context_t *m_context =
2080 ((coap_mbedtls_context_t *)c_context->dtls_context);
2081
2082 if (!m_context) {
2083 coap_log_warn("coap_context_set_pki_root_cas: (D)TLS environment "
2084 "not set up\n");
2085 return 0;
2086 }
2087
2088 if (ca_file == NULL && ca_path == NULL) {
2089 coap_log_warn("coap_context_set_pki_root_cas: ca_file and/or ca_path "
2090 "not defined\n");
2091 return 0;
2092 }
2093 if (m_context->root_ca_file) {
2094 mbedtls_free(m_context->root_ca_file);
2095 m_context->root_ca_file = NULL;
2096 }
2097
2098 if (ca_file) {
2099 m_context->root_ca_file = mbedtls_strdup(ca_file);
2100 }
2101
2102 if (m_context->root_ca_path) {
2103 mbedtls_free(m_context->root_ca_path);
2104 m_context->root_ca_path = NULL;
2105 }
2106
2107 if (ca_path) {
2108 m_context->root_ca_path = mbedtls_strdup(ca_path);
2109 }
2110 return 1;
2111}
2112
2113int
2115 coap_mbedtls_context_t *m_context =
2116 ((coap_mbedtls_context_t *)c_context->dtls_context);
2117 return m_context->psk_pki_enabled ? 1 : 0;
2118}
2119
2120void
2121coap_dtls_free_context(void *dtls_context) {
2122 coap_mbedtls_context_t *m_context = (coap_mbedtls_context_t *)dtls_context;
2123 unsigned int i;
2124
2125 for (i = 0; i < m_context->pki_sni_count; i++) {
2126 mbedtls_free(m_context->pki_sni_entry_list[i].sni);
2127
2128 mbedtls_x509_crt_free(&m_context->pki_sni_entry_list[i].public_cert);
2129
2130 mbedtls_pk_free(&m_context->pki_sni_entry_list[i].private_key);
2131
2132 mbedtls_x509_crt_free(&m_context->pki_sni_entry_list[i].cacert);
2133 }
2134 if (m_context->pki_sni_entry_list)
2135 mbedtls_free(m_context->pki_sni_entry_list);
2136
2137 for (i = 0; i < m_context->psk_sni_count; i++) {
2138 mbedtls_free(m_context->psk_sni_entry_list[i].sni);
2139 }
2140 if (m_context->psk_sni_entry_list)
2141 mbedtls_free(m_context->psk_sni_entry_list);
2142
2143 if (m_context->root_ca_path)
2144 mbedtls_free(m_context->root_ca_path);
2145 if (m_context->root_ca_file)
2146 mbedtls_free(m_context->root_ca_file);
2147
2148 mbedtls_free(m_context);
2149}
2150
2151#if COAP_CLIENT_SUPPORT
2152void *
2154#if !defined(MBEDTLS_SSL_CLI_C)
2155 (void)c_session;
2156 coap_log_emerg("coap_dtls_new_client_session:"
2157 " libcoap not compiled for Client Mode for Mbed TLS"
2158 " - update Mbed TLS to include Client Mode\n");
2159 return NULL;
2160#else /* MBEDTLS_SSL_CLI_C */
2161 coap_mbedtls_env_t *m_env = coap_dtls_new_mbedtls_env(c_session,
2164 int ret;
2165
2166 if (m_env) {
2167 coap_tick_t now;
2168
2169 coap_ticks(&now);
2170 m_env->last_timeout = now;
2171 ret = do_mbedtls_handshake(c_session, m_env);
2172 if (ret == -1) {
2173 coap_dtls_free_mbedtls_env(m_env);
2174 return NULL;
2175 }
2176 }
2177 return m_env;
2178#endif /* MBEDTLS_SSL_CLI_C */
2179}
2180#endif /* COAP_CLIENT_SUPPORT */
2181
2182#if COAP_SERVER_SUPPORT
2183void *
2185#if !defined(MBEDTLS_SSL_SRV_C)
2186 (void)c_session;
2187 coap_log_emerg("coap_dtls_new_server_session:"
2188 " libcoap not compiled for Server Mode for Mbed TLS"
2189 " - update Mbed TLS to include Server Mode\n");
2190 return NULL;
2191#else /* MBEDTLS_SSL_SRV_C */
2192 coap_mbedtls_env_t *m_env =
2193 (coap_mbedtls_env_t *)c_session->tls;
2194 if (m_env) {
2195#if defined(MBEDTLS_SSL_PROTO_DTLS)
2196#if MBEDTLS_VERSION_NUMBER >= 0x02100100
2197 mbedtls_ssl_set_mtu(&m_env->ssl, (uint16_t)c_session->mtu);
2198#endif /* MBEDTLS_VERSION_NUMBER >= 0x02100100 */
2199#endif /* MBEDTLS_SSL_PROTO_DTLS */
2200 }
2201 return m_env;
2202#endif /* MBEDTLS_SSL_SRV_C */
2203}
2204#endif /* COAP_SERVER_SUPPORT */
2205
2206void
2208 if (c_session && c_session->context && c_session->tls) {
2209 coap_dtls_free_mbedtls_env(c_session->tls);
2210 c_session->tls = NULL;
2212 }
2213 return;
2214}
2215
2216void
2218#if defined(MBEDTLS_SSL_PROTO_DTLS)
2219 coap_mbedtls_env_t *m_env =
2220 (coap_mbedtls_env_t *)c_session->tls;
2221 if (m_env) {
2222#if MBEDTLS_VERSION_NUMBER >= 0x02100100
2223 mbedtls_ssl_set_mtu(&m_env->ssl, (uint16_t)c_session->mtu);
2224#endif /* MBEDTLS_VERSION_NUMBER >= 0x02100100 */
2225 }
2226#else /* ! MBEDTLS_SSL_PROTO_DTLS */
2227 (void)c_session;
2228#endif /* MBEDTLS_SSL_PROTO_DTLS */
2229}
2230
2231ssize_t
2233 const uint8_t *data, size_t data_len) {
2234 int ret;
2235 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
2236
2237 assert(m_env != NULL);
2238
2239 if (!m_env) {
2240 return -1;
2241 }
2242 c_session->dtls_event = -1;
2243 coap_log_debug("* %s: dtls: sent %4d bytes\n",
2244 coap_session_str(c_session), (int)data_len);
2245 if (m_env->established) {
2246 ret = mbedtls_ssl_write(&m_env->ssl, (const unsigned char *) data, data_len);
2247 if (ret <= 0) {
2248 switch (ret) {
2249 case MBEDTLS_ERR_SSL_WANT_READ:
2250 case MBEDTLS_ERR_SSL_WANT_WRITE:
2251 ret = 0;
2252 break;
2253 case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
2255 ret = -1;
2256 break;
2257 default:
2258 coap_log_warn("coap_dtls_send: "
2259 "returned -0x%x: '%s'\n",
2260 -ret, get_error_string(ret));
2261 ret = -1;
2262 break;
2263 }
2264 if (ret == -1) {
2265 coap_log_warn("coap_dtls_send: cannot send PDU\n");
2266 }
2267 }
2268 } else {
2269 ret = do_mbedtls_handshake(c_session, m_env);
2270 if (ret == 1) {
2271 /* Just connected, so send the data */
2272 return coap_dtls_send(c_session, data, data_len);
2273 }
2274 ret = -1;
2275 }
2276
2277 if (c_session->dtls_event >= 0) {
2278 /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected_lkd() */
2279 if (c_session->dtls_event != COAP_EVENT_DTLS_CLOSED)
2280 coap_handle_event_lkd(c_session->context, c_session->dtls_event, c_session);
2281 if (c_session->dtls_event == COAP_EVENT_DTLS_ERROR ||
2282 c_session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
2284 ret = -1;
2285 }
2286 }
2287 return ret;
2288}
2289
2290int
2292 return 0;
2293}
2294
2296coap_dtls_get_context_timeout(void *dtls_context COAP_UNUSED) {
2297 return 0;
2298}
2299
2302 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
2303 int ret = mbedtls_timing_get_delay(&m_env->timer);
2304 unsigned int scalar = 1 << m_env->retry_scalar;
2305
2306 assert(c_session->state == COAP_SESSION_STATE_HANDSHAKE);
2307 switch (ret) {
2308 case 0:
2309 /* int_ms has not timed out */
2310 if (m_env->last_timeout + COAP_DTLS_RETRANSMIT_COAP_TICKS * scalar > now) {
2311 /* Need to indicate remaining timeout time */
2312 return m_env->last_timeout + COAP_DTLS_RETRANSMIT_COAP_TICKS * scalar;
2313 }
2314 m_env->last_timeout = now;
2315 /* This may cause a minor extra delay */
2316 return now + COAP_DTLS_RETRANSMIT_COAP_TICKS * scalar;
2317 case 1:
2318 /* int_ms has timed out, but not fin_ms */
2319 /*
2320 * Need to make sure that we do not do this too frequently
2321 */
2322 if (m_env->last_timeout + COAP_DTLS_RETRANSMIT_COAP_TICKS * scalar > now) {
2323 return m_env->last_timeout + COAP_DTLS_RETRANSMIT_COAP_TICKS * scalar;
2324 }
2325
2326 /* Reset for the next time */
2327 m_env->last_timeout = now;
2328 return now;
2329 case 2:
2330 /* fin_ms has timed out - timed out - one final try */
2331 return now;
2332 default:
2333 break;
2334 }
2335
2336 return 0;
2337}
2338
2339/*
2340 * return 1 timed out
2341 * 0 still timing out
2342 */
2343int
2345 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
2346
2347 assert(m_env != NULL && c_session->state == COAP_SESSION_STATE_HANDSHAKE);
2348 m_env->retry_scalar++;
2349 if ((++c_session->dtls_timeout_count > c_session->max_retransmit) ||
2350 (do_mbedtls_handshake(c_session, m_env) < 0)) {
2351 /* Too many retries */
2353 return 1;
2354 }
2355 return 0;
2356}
2357
2358/*
2359 * return +ve data amount
2360 * 0 no more
2361 * -1 error
2362 */
2363int
2365 const uint8_t *data,
2366 size_t data_len) {
2367 int ret = 1;
2368
2369 c_session->dtls_event = -1;
2370 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
2371 coap_ssl_t *ssl_data;
2372
2373 assert(m_env != NULL);
2374
2375 ssl_data = &m_env->coap_ssl_data;
2376 if (ssl_data->pdu_len) {
2377 coap_log_err("** %s: Previous data not read %u bytes\n",
2378 coap_session_str(c_session), ssl_data->pdu_len);
2379 }
2380 ssl_data->pdu = data;
2381 ssl_data->pdu_len = (unsigned)data_len;
2382
2383 if (m_env->established) {
2384#if COAP_CONSTRAINED_STACK
2385 /* pdu can be protected by global_lock if needed */
2386 static uint8_t pdu[COAP_RXBUFFER_SIZE];
2387#else /* ! COAP_CONSTRAINED_STACK */
2388 uint8_t pdu[COAP_RXBUFFER_SIZE];
2389#endif /* ! COAP_CONSTRAINED_STACK */
2390
2391 if (c_session->state == COAP_SESSION_STATE_HANDSHAKE) {
2393 c_session);
2394 c_session->sock.lfunc[COAP_LAYER_TLS].l_establish(c_session);
2395 }
2396
2397 ret = mbedtls_ssl_read(&m_env->ssl, pdu, sizeof(pdu));
2398 if (ret > 0) {
2399 ret = coap_handle_dgram(c_session->context, c_session, pdu, (size_t)ret);
2400 goto finish;
2401 }
2402 switch (ret) {
2403 case 0:
2404 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
2405 case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
2407 break;
2408 case MBEDTLS_ERR_SSL_WANT_READ:
2409 break;
2410 default:
2411 coap_log_warn("coap_dtls_receive: "
2412 "returned -0x%x: '%s' (length %zd)\n",
2413 -ret, get_error_string(ret), data_len);
2414 break;
2415 }
2416 ret = -1;
2417 } else {
2418 ret = do_mbedtls_handshake(c_session, m_env);
2419 if (ret == 1) {
2420 /* Just connected, so send the data */
2421 coap_session_connected(c_session);
2422 } else {
2423 if (ssl_data->pdu_len) {
2424 /* Do the handshake again incase of internal timeout */
2425 ret = do_mbedtls_handshake(c_session, m_env);
2426 if (ret == 1) {
2427 /* Just connected, so send the data */
2428 coap_session_connected(c_session);
2429 }
2430 }
2431 ret = -1;
2432 }
2433 }
2434 if (c_session->dtls_event >= 0) {
2435 /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected_lkd() */
2436 if (c_session->dtls_event != COAP_EVENT_DTLS_CLOSED)
2437 coap_handle_event_lkd(c_session->context, c_session->dtls_event, c_session);
2438 if (c_session->dtls_event == COAP_EVENT_DTLS_ERROR ||
2439 c_session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
2441 ssl_data = NULL;
2442 ret = -1;
2443 }
2444 }
2445finish:
2446 if (ssl_data && ssl_data->pdu_len) {
2447 /* pdu data is held on stack which will not stay there */
2448 coap_log_debug("coap_dtls_receive: ret %d: remaining data %u\n", ret, ssl_data->pdu_len);
2449 ssl_data->pdu_len = 0;
2450 ssl_data->pdu = NULL;
2451 }
2452 if (ret > 0) {
2453 coap_log_debug("* %s: dtls: recv %4d bytes\n",
2454 coap_session_str(c_session), ret);
2455 }
2456 return ret;
2457}
2458
2459#if COAP_SERVER_SUPPORT
2460/*
2461 * return -1 failure
2462 * 0 not completed
2463 * 1 client hello seen
2464 */
2465int
2467 const uint8_t *data,
2468 size_t data_len) {
2469#if !defined(MBEDTLS_SSL_PROTO_DTLS) || !defined(MBEDTLS_SSL_SRV_C)
2470 (void)c_session;
2471 (void)data;
2472 (void)data_len;
2473 coap_log_emerg("coap_dtls_hello:"
2474 " libcoap not compiled for DTLS or Server Mode for Mbed TLS"
2475 " - update Mbed TLS to include DTLS and Server Mode\n");
2476 return -1;
2477#else /* MBEDTLS_SSL_PROTO_DTLS && MBEDTLS_SSL_SRV_C */
2478 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
2479 coap_ssl_t *ssl_data;
2480 int ret;
2481
2482 if (!m_env) {
2483 m_env = coap_dtls_new_mbedtls_env(c_session, COAP_DTLS_ROLE_SERVER,
2485 if (m_env) {
2486 c_session->tls = m_env;
2487 } else {
2488 /* error should have already been reported */
2489 return -1;
2490 }
2491 }
2492
2493 if ((ret = mbedtls_ssl_set_client_transport_id(&m_env->ssl,
2494 (unsigned char *)&c_session->addr_info.remote,
2495 sizeof(c_session->addr_info.remote))) != 0) {
2496 coap_log_err("mbedtls_ssl_set_client_transport_id() returned -0x%x: '%s'\n",
2497 -ret, get_error_string(ret));
2498 return -1;
2499 }
2500
2501 ssl_data = &m_env->coap_ssl_data;
2502 if (ssl_data->pdu_len) {
2503 coap_log_err("** %s: Previous data not read %u bytes\n",
2504 coap_session_str(c_session), ssl_data->pdu_len);
2505 }
2506 ssl_data->pdu = data;
2507 ssl_data->pdu_len = (unsigned)data_len;
2508
2509 ret = do_mbedtls_handshake(c_session, m_env);
2510 if (ret == 0 || m_env->seen_client_hello) {
2511 /* The test for seen_client_hello gives the ability to setup a new
2512 c_session to continue the do_mbedtls_handshake past the client hello
2513 and safely allow updating of the m_env and separately
2514 letting a new session cleanly start up.
2515 */
2516 m_env->seen_client_hello = 0;
2517 ret = 1;
2518 } else {
2519 ret = 0;
2520 }
2521
2522 if (ssl_data->pdu_len) {
2523 /* pdu data is held on stack which will not stay there */
2524 coap_log_debug("coap_dtls_hello: ret %d: remaining data %u\n", ret, ssl_data->pdu_len);
2525 ssl_data->pdu_len = 0;
2526 ssl_data->pdu = NULL;
2527 }
2528 return ret;
2529#endif /* MBEDTLS_SSL_PROTO_DTLS && MBEDTLS_SSL_SRV_C */
2530}
2531#endif /* COAP_SERVER_SUPPORT */
2532
2533unsigned int
2535 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
2536 int expansion = mbedtls_ssl_get_record_expansion(&m_env->ssl);
2537
2538 if (expansion == MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) {
2539 return 13 + 8 + 8;
2540 }
2541 return expansion;
2542}
2543
2544#if !COAP_DISABLE_TCP
2545#if COAP_CLIENT_SUPPORT
2546void *
2548#if !defined(MBEDTLS_SSL_CLI_C)
2549 (void)c_session;
2550 *connected = 0;
2551 coap_log_emerg("coap_tls_new_client_session:"
2552 " libcoap not compiled for Client Mode for Mbed TLS"
2553 " - update Mbed TLS to include Client Mode\n");
2554 return NULL;
2555#else /* MBEDTLS_SSL_CLI_C */
2556 coap_mbedtls_env_t *m_env = coap_dtls_new_mbedtls_env(c_session,
2559 int ret;
2560 coap_tick_t now;
2561 coap_ticks(&now);
2562
2563 if (!m_env)
2564 return NULL;
2565
2566 m_env->last_timeout = now;
2567 c_session->tls = m_env;
2568 ret = do_mbedtls_handshake(c_session, m_env);
2569 if (ret == 1) {
2571 c_session->sock.lfunc[COAP_LAYER_TLS].l_establish(c_session);
2572 }
2573 return m_env;
2574#endif /* MBEDTLS_SSL_CLI_C */
2575}
2576#endif /* COAP_CLIENT_SUPPORT */
2577
2578#if COAP_SERVER_SUPPORT
2579void *
2581#if !defined(MBEDTLS_SSL_SRV_C)
2582 (void)c_session;
2583 (void)connected;
2584
2585 coap_log_emerg("coap_tls_new_server_session:"
2586 " libcoap not compiled for Server Mode for Mbed TLS"
2587 " - update Mbed TLS to include Server Mode\n");
2588 return NULL;
2589#else /* MBEDTLS_SSL_SRV_C */
2590 coap_mbedtls_env_t *m_env = coap_dtls_new_mbedtls_env(c_session,
2593 int ret;
2594
2595 if (!m_env)
2596 return NULL;
2597
2598 c_session->tls = m_env;
2599 ret = do_mbedtls_handshake(c_session, m_env);
2600 if (ret == 1) {
2602 c_session->sock.lfunc[COAP_LAYER_TLS].l_establish(c_session);
2603 }
2604 return m_env;
2605#endif /* MBEDTLS_SSL_SRV_C */
2606}
2607#endif /* COAP_SERVER_SUPPORT */
2608
2609void
2611 coap_dtls_free_session(c_session);
2612 return;
2613}
2614
2615/*
2616 * strm
2617 * return +ve Number of bytes written.
2618 * -1 Error (error in errno).
2619 */
2620ssize_t
2621coap_tls_write(coap_session_t *c_session, const uint8_t *data,
2622 size_t data_len) {
2623 int ret = 0;
2624 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
2625 size_t amount_sent = 0;
2626
2627 assert(m_env != NULL);
2628
2629 if (!m_env) {
2630 errno = ENXIO;
2631 return -1;
2632 }
2633 c_session->dtls_event = -1;
2634 if (m_env->established) {
2635 while (amount_sent < data_len) {
2636 ret = mbedtls_ssl_write(&m_env->ssl, &data[amount_sent],
2637 data_len - amount_sent);
2638 if (ret <= 0) {
2639 switch (ret) {
2640 case MBEDTLS_ERR_SSL_WANT_READ:
2641 case MBEDTLS_ERR_SSL_WANT_WRITE:
2642 if (amount_sent)
2643 ret = amount_sent;
2644 else
2645 ret = 0;
2646 c_session->sock.flags |= COAP_SOCKET_WANT_WRITE;
2647 break;
2648 case MBEDTLS_ERR_NET_CONN_RESET:
2649 case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
2651 break;
2652 default:
2653 coap_log_warn("coap_tls_write: "
2654 "returned -0x%x: '%s'\n",
2655 -ret, get_error_string(ret));
2656 ret = -1;
2657 break;
2658 }
2659 if (ret == -1) {
2660 coap_log_warn("coap_tls_write: cannot send PDU\n");
2661 }
2662 break;
2663 }
2664 amount_sent += ret;
2665 }
2666 } else {
2667 ret = do_mbedtls_handshake(c_session, m_env);
2668 if (ret == 1) {
2670 c_session);
2671 c_session->sock.lfunc[COAP_LAYER_TLS].l_establish(c_session);
2672 } else {
2673 ret = -1;
2674 }
2675 }
2676
2677 if (c_session->dtls_event >= 0) {
2678 /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected_lkd() */
2679 if (c_session->dtls_event != COAP_EVENT_DTLS_CLOSED)
2680 coap_handle_event_lkd(c_session->context, c_session->dtls_event, c_session);
2681 if (c_session->dtls_event == COAP_EVENT_DTLS_ERROR ||
2682 c_session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
2684 ret = -1;
2685 }
2686 }
2687 if (ret > 0) {
2688 if (ret == (ssize_t)data_len)
2689 coap_log_debug("* %s: tls: sent %4d bytes\n",
2690 coap_session_str(c_session), ret);
2691 else
2692 coap_log_debug("* %s: tls: sent %4d of %4zd bytes\n",
2693 coap_session_str(c_session), ret, data_len);
2694 }
2695 return ret;
2696}
2697
2698/*
2699 * strm
2700 * return >=0 Number of bytes read.
2701 * -1 Error (error in errno).
2702 */
2703ssize_t
2704coap_tls_read(coap_session_t *c_session, uint8_t *data, size_t data_len) {
2705 int ret = -1;
2706
2707 coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls;
2708
2709 if (!m_env) {
2710 errno = ENXIO;
2711 return -1;
2712 }
2713
2714 c_session->dtls_event = -1;
2715
2716 if (!m_env->established && !m_env->sent_alert) {
2717 ret = do_mbedtls_handshake(c_session, m_env);
2718 if (ret == 1) {
2720 c_session);
2721 c_session->sock.lfunc[COAP_LAYER_TLS].l_establish(c_session);
2722 }
2723 }
2724
2725 if (c_session->state != COAP_SESSION_STATE_NONE && m_env->established) {
2726 ret = mbedtls_ssl_read(&m_env->ssl, data, data_len);
2727 if (ret <= 0) {
2728 switch (ret) {
2729 case 0:
2730 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
2732 ret = -1;
2733 break;
2734 case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
2735 /* Stop the sending of an alert on closedown */
2736 m_env->sent_alert = 1;
2738 break;
2739#if MBEDTLS_VERSION_NUMBER >= 0x03060000
2740 case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET:
2741#endif /* MBEDTLS_VERSION_NUMBER >= 0x03060000 */
2742 case MBEDTLS_ERR_SSL_WANT_READ:
2743 errno = EAGAIN;
2744 ret = 0;
2745 break;
2746 default:
2747 coap_log_warn("coap_tls_read: "
2748 "returned -0x%x: '%s' (length %zd)\n",
2749 -ret, get_error_string(ret), data_len);
2750 ret = -1;
2751 break;
2752 }
2753 } else if (ret < (int)data_len) {
2754 c_session->sock.flags &= ~COAP_SOCKET_CAN_READ;
2755 }
2756 }
2757
2758 if (c_session->dtls_event >= 0) {
2759 /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected_lkd() */
2760 if (c_session->dtls_event != COAP_EVENT_DTLS_CLOSED)
2761 coap_handle_event_lkd(c_session->context, c_session->dtls_event, c_session);
2762 if (c_session->dtls_event == COAP_EVENT_DTLS_ERROR ||
2763 c_session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
2765 ret = -1;
2766 }
2767 }
2768 if (ret > 0) {
2769 coap_log_debug("* %s: tls: recv %4d bytes\n",
2770 coap_session_str(c_session), ret);
2771 }
2772 return ret;
2773}
2774#endif /* !COAP_DISABLE_TCP */
2775
2776void
2777coap_dtls_startup(void) {
2778}
2779
2780void
2781coap_dtls_shutdown(void) {
2782#if COAP_CLIENT_SUPPORT
2783 mbedtls_free(psk_ciphers);
2784 mbedtls_free(pki_ciphers);
2785 mbedtls_free(ecjpake_ciphers);
2786 psk_ciphers = NULL;
2787 pki_ciphers = NULL;
2788 ecjpake_ciphers = NULL;
2789 processed_ciphers = 0;
2790#endif /* COAP_CLIENT_SUPPORT */
2792}
2793
2794void *
2795coap_dtls_get_tls(const coap_session_t *c_session,
2796 coap_tls_library_t *tls_lib) {
2797 if (tls_lib)
2798 *tls_lib = COAP_TLS_LIBRARY_MBEDTLS;
2799 if (c_session && c_session->tls) {
2800 coap_mbedtls_env_t *m_env;
2801
2802 /* To get around const issue */
2803 memcpy(&m_env, &c_session->tls, sizeof(m_env));
2804
2805 return (void *)&m_env->ssl;
2806 }
2807 return NULL;
2808}
2809
2810static coap_log_t keep_log_level = COAP_LOG_EMERG;
2811
2812void
2814#if !defined(ESPIDF_VERSION)
2815 int use_level;
2816 /*
2817 * Mbed TLS debug levels filter
2818 * 0 No debug
2819 * 1 Error
2820 * 2 State change
2821 * 3 Informational
2822 * 4 Verbose
2823 */
2824 switch ((int)level) {
2825 case COAP_LOG_EMERG:
2826 use_level = 0;
2827 break;
2828 case COAP_LOG_ALERT:
2829 case COAP_LOG_CRIT:
2830 case COAP_LOG_ERR:
2831 case COAP_LOG_WARN:
2832 use_level = 1;
2833 break;
2834 case COAP_LOG_NOTICE:
2835 use_level = 2;
2836 break;
2837 case COAP_LOG_INFO:
2838 use_level = 3;
2839 break;
2840 case COAP_LOG_DEBUG:
2841 default:
2842 use_level = 4;
2843 break;
2844 }
2845 mbedtls_debug_set_threshold(use_level);
2846#endif /* !ESPIDF_VERSION) */
2847 keep_log_level = level;
2848}
2849
2852 return keep_log_level;
2853}
2854
2857 static coap_tls_version_t version;
2858 version.version = mbedtls_version_get_number();
2859 version.built_version = MBEDTLS_VERSION_NUMBER;
2861 return &version;
2862}
2863
2864#if COAP_SERVER_SUPPORT
2866coap_digest_setup(void) {
2867 mbedtls_sha256_context *digest_ctx = mbedtls_malloc(sizeof(mbedtls_sha256_context));
2868
2869 if (digest_ctx) {
2870 mbedtls_sha256_init(digest_ctx);
2871#ifdef MBEDTLS_2_X_COMPAT
2872 if (mbedtls_sha256_starts_ret(digest_ctx, 0) != 0) {
2873#else
2874 if (mbedtls_sha256_starts(digest_ctx, 0) != 0) {
2875#endif /* MBEDTLS_2_X_COMPAT */
2876 coap_digest_free(digest_ctx);
2877 return NULL;
2878 }
2879 }
2880 return digest_ctx;
2881}
2882
2883void
2885 if (digest_ctx) {
2886 mbedtls_sha256_free(digest_ctx);
2887 mbedtls_free(digest_ctx);
2888 }
2889}
2890
2891int
2893 const uint8_t *data,
2894 size_t data_len) {
2895#ifdef MBEDTLS_2_X_COMPAT
2896 int ret = mbedtls_sha256_update_ret(digest_ctx, data, data_len);
2897#else
2898 int ret = mbedtls_sha256_update(digest_ctx, data, data_len);
2899#endif /* MBEDTLS_2_X_COMPAT */
2900
2901 return ret == 0;
2902}
2903
2904int
2906 coap_digest_t *digest_buffer) {
2907#ifdef MBEDTLS_2_X_COMPAT
2908 int ret = mbedtls_sha256_finish_ret(digest_ctx, (uint8_t *)digest_buffer);
2909#else
2910 int ret = mbedtls_sha256_finish(digest_ctx, (uint8_t *)digest_buffer);
2911#endif /* MBEDTLS_2_X_COMPAT */
2912
2913 coap_digest_free(digest_ctx);
2914 return ret == 0;
2915}
2916#endif /* COAP_SERVER_SUPPORT */
2917
2918#include <mbedtls/cipher.h>
2919#include <mbedtls/md.h>
2920
2921#ifndef MBEDTLS_CIPHER_MODE_AEAD
2922#error need MBEDTLS_CIPHER_MODE_AEAD, please enable MBEDTLS_CCM_C
2923#endif /* MBEDTLS_CIPHER_MODE_AEAD */
2924
2925#ifdef MBEDTLS_ERROR_C
2926#include <mbedtls/error.h>
2927#endif /* MBEDTLS_ERROR_C */
2928
2929#ifdef MBEDTLS_ERROR_C
2930#define C(Func) \
2931 do { \
2932 int c_tmp = (int)(Func); \
2933 if (c_tmp != 0) { \
2934 char error_buf[64]; \
2935 mbedtls_strerror(c_tmp, error_buf, sizeof(error_buf)); \
2936 coap_log_err("mbedtls: -0x%04x: %s\n", -c_tmp, error_buf); \
2937 goto error; \
2938 } \
2939 } while (0);
2940#else /* !MBEDTLS_ERROR_C */
2941#define C(Func) \
2942 do { \
2943 int c_tmp = (int)(Func); \
2944 if (c_tmp != 0) { \
2945 coap_log_err("mbedtls: %d\n", tmp); \
2946 goto error; \
2947 } \
2948 } while (0);
2949#endif /* !MBEDTLS_ERROR_C */
2950
2951#if COAP_WS_SUPPORT
2952/*
2953 * The struct hash_algs and the function get_hash_alg() are used to
2954 * determine which hash type to use for creating the required hash object.
2955 */
2956static struct hash_algs {
2957 cose_alg_t alg;
2958 mbedtls_md_type_t hash_type;
2959 size_t hash_size;
2960} hashs[] = {
2961 {COSE_ALGORITHM_SHA_1, MBEDTLS_MD_SHA1, 20},
2962 {COSE_ALGORITHM_SHA_256_256, MBEDTLS_MD_SHA256, 32},
2963 {COSE_ALGORITHM_SHA_512, MBEDTLS_MD_SHA512, 64},
2964};
2965
2966static mbedtls_md_type_t
2967get_hash_alg(cose_alg_t alg, size_t *hash_len) {
2968 size_t idx;
2969
2970 for (idx = 0; idx < sizeof(hashs) / sizeof(struct hash_algs); idx++) {
2971 if (hashs[idx].alg == alg) {
2972 *hash_len = hashs[idx].hash_size;
2973 return hashs[idx].hash_type;
2974 }
2975 }
2976 coap_log_debug("get_hash_alg: COSE hash %d not supported\n", alg);
2977 return MBEDTLS_MD_NONE;
2978}
2979
2980int
2982 const coap_bin_const_t *data,
2983 coap_bin_const_t **hash) {
2984 mbedtls_md_context_t ctx;
2985 int ret = 0;
2986 const mbedtls_md_info_t *md_info;
2987 unsigned int len;
2988 coap_binary_t *dummy = NULL;
2989 size_t hash_length;
2990 mbedtls_md_type_t dig_type = get_hash_alg(alg, &hash_length);
2991
2992 if (dig_type == MBEDTLS_MD_NONE) {
2993 coap_log_debug("coap_crypto_hash: algorithm %d not supported\n", alg);
2994 return 0;
2995 }
2996 md_info = mbedtls_md_info_from_type(dig_type);
2997
2998 len = mbedtls_md_get_size(md_info);
2999 if (len == 0) {
3000 return 0;
3001 }
3002
3003 mbedtls_md_init(&ctx);
3004 C(mbedtls_md_setup(&ctx, md_info, 0));
3005
3006 C(mbedtls_md_starts(&ctx));
3007 C(mbedtls_md_update(&ctx, (const unsigned char *)data->s, data->length));
3008 dummy = coap_new_binary(len);
3009 if (dummy == NULL)
3010 goto error;
3011 C(mbedtls_md_finish(&ctx, dummy->s));
3012
3013 *hash = (coap_bin_const_t *)dummy;
3014 ret = 1;
3015error:
3016 mbedtls_md_free(&ctx);
3017 return ret;
3018}
3019#endif /* COAP_WS_SUPPORT */
3020
3021#if COAP_OSCORE_SUPPORT
3022int
3024 return 1;
3025}
3026
3027/*
3028 * The struct cipher_algs and the function get_cipher_alg() are used to
3029 * determine which cipher type to use for creating the required cipher
3030 * suite object.
3031 */
3032static struct cipher_algs {
3033 cose_alg_t alg;
3034 mbedtls_cipher_type_t cipher_type;
3035} ciphers[] = {{COSE_ALGORITHM_AES_CCM_16_64_128, MBEDTLS_CIPHER_AES_128_CCM},
3036 {COSE_ALGORITHM_AES_CCM_16_64_256, MBEDTLS_CIPHER_AES_256_CCM}
3037};
3038
3039static mbedtls_cipher_type_t
3040get_cipher_alg(cose_alg_t alg) {
3041 size_t idx;
3042
3043 for (idx = 0; idx < sizeof(ciphers) / sizeof(struct cipher_algs); idx++) {
3044 if (ciphers[idx].alg == alg)
3045 return ciphers[idx].cipher_type;
3046 }
3047 coap_log_debug("get_cipher_alg: COSE cipher %d not supported\n", alg);
3048 return 0;
3049}
3050
3051/*
3052 * The struct hmac_algs and the function get_hmac_alg() are used to
3053 * determine which hmac type to use for creating the required hmac
3054 * suite object.
3055 */
3056static struct hmac_algs {
3057 cose_hmac_alg_t hmac_alg;
3058 mbedtls_md_type_t hmac_type;
3059} hmacs[] = {
3060 {COSE_HMAC_ALG_HMAC256_256, MBEDTLS_MD_SHA256},
3061 {COSE_HMAC_ALG_HMAC384_384, MBEDTLS_MD_SHA384},
3062 {COSE_HMAC_ALG_HMAC512_512, MBEDTLS_MD_SHA512},
3063};
3064
3065static mbedtls_md_type_t
3066get_hmac_alg(cose_hmac_alg_t hmac_alg) {
3067 size_t idx;
3068
3069 for (idx = 0; idx < sizeof(hmacs) / sizeof(struct hmac_algs); idx++) {
3070 if (hmacs[idx].hmac_alg == hmac_alg)
3071 return hmacs[idx].hmac_type;
3072 }
3073 coap_log_debug("get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg);
3074 return 0;
3075}
3076
3077int
3079 return get_cipher_alg(alg) != 0;
3080}
3081
3082int
3084 cose_hmac_alg_t hmac_alg;
3085
3086 if (!cose_get_hmac_alg_for_hkdf(hkdf_alg, &hmac_alg))
3087 return 0;
3088 return get_hmac_alg(hmac_alg) != 0;
3089}
3090
3095static int
3096setup_cipher_context(mbedtls_cipher_context_t *ctx,
3097 cose_alg_t coap_alg,
3098 const uint8_t *key_data,
3099 size_t key_length,
3100 mbedtls_operation_t mode) {
3101 const mbedtls_cipher_info_t *cipher_info;
3102 mbedtls_cipher_type_t cipher_type;
3103 uint8_t key[COAP_CRYPTO_MAX_KEY_SIZE]; /* buffer for normalizing the key
3104 according to its key length */
3105 int klen;
3106 memset(key, 0, sizeof(key));
3107
3108 if ((cipher_type = get_cipher_alg(coap_alg)) == 0) {
3109 coap_log_debug("coap_crypto_encrypt: algorithm %d not supported\n",
3110 coap_alg);
3111 return 0;
3112 }
3113 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
3114 if (!cipher_info) {
3115 coap_log_crit("coap_crypto_encrypt: cannot get cipher info\n");
3116 return 0;
3117 }
3118
3119 mbedtls_cipher_init(ctx);
3120
3121 C(mbedtls_cipher_setup(ctx, cipher_info));
3122 klen = mbedtls_cipher_get_key_bitlen(ctx);
3123 if ((klen > (int)(sizeof(key) * 8)) || (key_length > sizeof(key))) {
3124 coap_log_crit("coap_crypto: cannot set key\n");
3125 goto error;
3126 }
3127 memcpy(key, key_data, key_length);
3128 C(mbedtls_cipher_setkey(ctx, key, klen, mode));
3129
3130 /* On success, the cipher context is released by the caller. */
3131 return 1;
3132error:
3133 mbedtls_cipher_free(ctx);
3134 return 0;
3135}
3136
3137int
3139 coap_bin_const_t *data,
3140 coap_bin_const_t *aad,
3141 uint8_t *result,
3142 size_t *max_result_len) {
3143 mbedtls_cipher_context_t ctx;
3144 const coap_crypto_aes_ccm_t *ccm;
3145#if (MBEDTLS_VERSION_NUMBER < 0x02150000)
3146 unsigned char tag[16];
3147#endif /* MBEDTLS_VERSION_NUMBER < 0x02150000 */
3148 int ret = 0;
3149 size_t result_len = *max_result_len;
3150 coap_bin_const_t laad;
3151
3152 if (data == NULL)
3153 return 0;
3154
3155 assert(params != NULL);
3156
3157 if (!params) {
3158 return 0;
3159 }
3160 ccm = &params->params.aes;
3161
3162 if (!setup_cipher_context(&ctx,
3163 params->alg,
3164 ccm->key.s,
3165 ccm->key.length,
3166 MBEDTLS_ENCRYPT)) {
3167 return 0;
3168 }
3169
3170 if (aad) {
3171 laad = *aad;
3172 } else {
3173 laad.s = NULL;
3174 laad.length = 0;
3175 }
3176
3177#if (MBEDTLS_VERSION_NUMBER < 0x02150000)
3178 C(mbedtls_cipher_auth_encrypt(&ctx,
3179 ccm->nonce,
3180 15 - ccm->l, /* iv */
3181 laad.s,
3182 laad.length, /* ad */
3183 data->s,
3184 data->length, /* input */
3185 result,
3186 &result_len, /* output */
3187 tag,
3188 ccm->tag_len /* tag */
3189 ));
3190 /* check if buffer is sufficient to hold tag */
3191 if ((result_len + ccm->tag_len) > *max_result_len) {
3192 coap_log_err("coap_encrypt: buffer too small\n");
3193 goto error;
3194 }
3195 /* append tag to result */
3196 memcpy(result + result_len, tag, ccm->tag_len);
3197 *max_result_len = result_len + ccm->tag_len;
3198 ret = 1;
3199#else /* MBEDTLS_VERSION_NUMBER >= 0x02150000 */
3200 C(mbedtls_cipher_auth_encrypt_ext(&ctx,
3201 ccm->nonce,
3202 15 - ccm->l, /* iv */
3203 laad.s,
3204 laad.length, /* ad */
3205 data->s,
3206 data->length, /* input */
3207 result,
3208 result_len,
3209 &result_len, /* output */
3210 ccm->tag_len /* tag */
3211 ));
3212 *max_result_len = result_len;
3213 ret = 1;
3214#endif /* MBEDTLS_VERSION_NUMBER >= 0x02150000 */
3215
3216error:
3217 mbedtls_cipher_free(&ctx);
3218 return ret;
3219}
3220
3221int
3223 coap_bin_const_t *data,
3224 coap_bin_const_t *aad,
3225 uint8_t *result,
3226 size_t *max_result_len) {
3227 mbedtls_cipher_context_t ctx;
3228 const coap_crypto_aes_ccm_t *ccm;
3229#if (MBEDTLS_VERSION_NUMBER < 0x02150000)
3230 const unsigned char *tag;
3231#endif /* MBEDTLS_VERSION_NUMBER < 0x02150000 */
3232 int ret = 0;
3233 size_t result_len = *max_result_len;
3234 coap_bin_const_t laad;
3235
3236 if (data == NULL)
3237 return 0;
3238
3239 assert(params != NULL);
3240
3241 if (!params) {
3242 return 0;
3243 }
3244
3245 ccm = &params->params.aes;
3246
3247 if (!setup_cipher_context(&ctx,
3248 params->alg,
3249 ccm->key.s,
3250 ccm->key.length,
3251 MBEDTLS_DECRYPT)) {
3252 return 0;
3253 }
3254
3255 if (data->length < ccm->tag_len) {
3256 coap_log_err("coap_decrypt: invalid tag length\n");
3257 goto error;
3258 }
3259
3260 if (aad) {
3261 laad = *aad;
3262 } else {
3263 laad.s = NULL;
3264 laad.length = 0;
3265 }
3266
3267#if (MBEDTLS_VERSION_NUMBER < 0x02150000)
3268 tag = data->s + data->length - ccm->tag_len;
3269 C(mbedtls_cipher_auth_decrypt(&ctx,
3270 ccm->nonce,
3271 15 - ccm->l, /* iv */
3272 laad.s,
3273 laad.length, /* ad */
3274 data->s,
3275 data->length - ccm->tag_len, /* input */
3276 result,
3277 &result_len, /* output */
3278 tag,
3279 ccm->tag_len /* tag */
3280 ));
3281#else /* MBEDTLS_VERSION_NUMBER >= 0x02150000 */
3282 C(mbedtls_cipher_auth_decrypt_ext(&ctx,
3283 ccm->nonce,
3284 15 - ccm->l, /* iv */
3285 laad.s,
3286 laad.length, /* ad */
3287 data->s,
3288 // data->length - ccm->tag_len, /* input */
3289 data->length, /* input */
3290 result,
3291 result_len,
3292 &result_len, /* output */
3293 ccm->tag_len /* tag */
3294 ));
3295#endif /* MBEDTLS_VERSION_NUMBER >= 0x02150000 */
3296
3297 *max_result_len = result_len;
3298 ret = 1;
3299error:
3300 mbedtls_cipher_free(&ctx);
3301 return ret;
3302}
3303
3304int
3306 coap_bin_const_t *key,
3307 coap_bin_const_t *data,
3308 coap_bin_const_t **hmac) {
3309 mbedtls_md_context_t ctx;
3310 int ret = 0;
3311 const int use_hmac = 1;
3312 const mbedtls_md_info_t *md_info;
3313 mbedtls_md_type_t mac_algo;
3314 unsigned int len;
3315 coap_binary_t *dummy = NULL;
3316
3317 assert(key);
3318 assert(data);
3319 assert(hmac);
3320
3321 if ((mac_algo = get_hmac_alg(hmac_alg)) == 0) {
3322 coap_log_debug("coap_crypto_hmac: algorithm %d not supported\n", hmac_alg);
3323 return 0;
3324 }
3325 md_info = mbedtls_md_info_from_type(mac_algo);
3326
3327 len = mbedtls_md_get_size(md_info);
3328 if (len == 0) {
3329 return 0;
3330 }
3331
3332 mbedtls_md_init(&ctx);
3333 C(mbedtls_md_setup(&ctx, md_info, use_hmac));
3334
3335 C(mbedtls_md_hmac_starts(&ctx, key->s, key->length));
3336 C(mbedtls_md_hmac_update(&ctx, (const unsigned char *)data->s, data->length));
3337 dummy = coap_new_binary(len);
3338 if (dummy == NULL)
3339 goto error;
3340 C(mbedtls_md_hmac_finish(&ctx, dummy->s));
3341
3342 *hmac = (coap_bin_const_t *)dummy;
3343 ret = 1;
3344error:
3345 mbedtls_md_free(&ctx);
3346 return ret;
3347}
3348
3349#endif /* COAP_OSCORE_SUPPORT */
3350
3351#else /* !COAP_WITH_LIBMBEDTLS */
3352
3353#ifdef __clang__
3354/* Make compilers happy that do not like empty modules. As this function is
3355 * never used, we ignore -Wunused-function at the end of compiling this file
3356 */
3357#pragma GCC diagnostic ignored "-Wunused-function"
3358#endif
3359static inline void
3360dummy(void) {
3361}
3362
3363#endif /* COAP_WITH_LIBMBEDTLS */
#define COAP_SERVER_SUPPORT
#define PRIx32
const char * coap_socket_strerror(void)
Definition coap_io.c:2040
#define COAP_RXBUFFER_SIZE
Definition coap_io.h:29
@ COAP_NACK_TLS_FAILED
Definition coap_io.h:66
#define COAP_SOCKET_WANT_WRITE
non blocking socket is waiting for writing
@ COAP_LAYER_TLS
Library specific build wrapper for coap_internal.h.
static void dummy(void)
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)
Definition coap_notls.c:108
coap_tick_t coap_dtls_get_timeout(coap_session_t *session COAP_UNUSED, coap_tick_t now COAP_UNUSED)
Definition coap_notls.c:224
ssize_t coap_tls_read(coap_session_t *session COAP_UNUSED, uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
Definition coap_notls.c:296
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context COAP_UNUSED)
Definition coap_notls.c:219
int coap_dtls_receive(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
Definition coap_notls.c:238
void * coap_dtls_get_tls(const coap_session_t *c_session COAP_UNUSED, coap_tls_library_t *tls_lib)
Definition coap_notls.c:153
unsigned int coap_dtls_get_overhead(coap_session_t *session COAP_UNUSED)
Definition coap_notls.c:256
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx COAP_UNUSED)
Definition coap_notls.c:142
ssize_t coap_dtls_send(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
Definition coap_notls.c:207
ssize_t coap_tls_write(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
Definition coap_notls.c:284
void coap_dtls_session_update_mtu(coap_session_t *session COAP_UNUSED)
Definition coap_notls.c:203
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)
Definition coap_notls.c:116
int coap_dtls_handle_timeout(coap_session_t *session COAP_UNUSED)
Definition coap_notls.c:233
void coap_dtls_free_context(void *handle COAP_UNUSED)
Definition coap_notls.c:181
void coap_dtls_free_session(coap_session_t *coap_session COAP_UNUSED)
Definition coap_notls.c:199
void * coap_dtls_new_context(coap_context_t *coap_context COAP_UNUSED)
Definition coap_notls.c:176
void coap_tls_free_session(coap_session_t *coap_session COAP_UNUSED)
Definition coap_notls.c:275
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.
void coap_digest_ctx_t
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.
Definition coap_time.h:143
int coap_prng_lkd(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
Definition coap_prng.c:178
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.
Definition coap_net.c:4496
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.
Definition coap_net.c:2633
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.
#define COAP_CRYPTO_MAX_KEY_SIZE
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 *coap_session)
Get the current client's PSK identity.
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
Definition coap_notls.c:149
int coap_dtls_define_issue(coap_define_issue_key_t type, coap_define_issue_fail_t fail, coap_dtls_key_t *key, const coap_dtls_role_t role, int ret)
Report PKI DEFINE type issue.
Definition coap_dtls.c:165
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_set_cid_tuple_change(coap_context_t *context, uint8_t every)
Set the Connection ID client tuple frequency change for testing CIDs.
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
Definition coap_notls.c:214
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.
Definition coap_notls.c:161
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.
#define COAP_DTLS_RETRANSMIT_COAP_TICKS
void coap_dtls_map_key_type_to_define(const coap_dtls_pki_t *setup_data, coap_dtls_key_t *key)
Map the PKI key definitions to the new DEFINE format.
Definition coap_dtls.c:26
const coap_bin_const_t * coap_get_session_server_psk_key(const coap_session_t *coap_session)
Get the current server's PSK key.
@ COAP_DEFINE_KEY_PRIVATE
@ COAP_DEFINE_KEY_ROOT_CA
@ COAP_DEFINE_KEY_CA
@ COAP_DEFINE_KEY_PUBLIC
@ COAP_DEFINE_FAIL_NONE
@ COAP_DEFINE_FAIL_NOT_SUPPORTED
@ COAP_DEFINE_FAIL_BAD
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
Definition coap_notls.c:100
coap_dtls_role_t
Definition coap_dtls.h:44
coap_tls_library_t
Definition coap_dtls.h:70
@ COAP_PKI_KEY_DEF_PKCS11
The PKI key type is PKCS11 (pkcs11:...).
Definition coap_dtls.h:245
@ COAP_PKI_KEY_DEF_DER_BUF
The PKI key type is DER buffer (ASN.1).
Definition coap_dtls.h:242
@ COAP_PKI_KEY_DEF_PEM_BUF
The PKI key type is PEM buffer.
Definition coap_dtls.h:236
@ COAP_PKI_KEY_DEF_PEM
The PKI key type is PEM file.
Definition coap_dtls.h:234
@ COAP_PKI_KEY_DEF_ENGINE
The PKI key type is to be passed to ENGINE.
Definition coap_dtls.h:251
@ COAP_PKI_KEY_DEF_RPK_BUF
The PKI key type is RPK in buffer.
Definition coap_dtls.h:238
@ COAP_PKI_KEY_DEF_DER
The PKI key type is DER file.
Definition coap_dtls.h:240
@ COAP_PKI_KEY_DEF_PKCS11_RPK
The PKI key type is PKCS11 w/ RPK (pkcs11:...).
Definition coap_dtls.h:248
@ COAP_DTLS_ROLE_SERVER
Internal function invoked for server.
Definition coap_dtls.h:46
@ COAP_DTLS_ROLE_CLIENT
Internal function invoked for client.
Definition coap_dtls.h:45
@ COAP_PKI_KEY_DEFINE
The individual PKI key types are Definable.
Definition coap_dtls.h:172
@ COAP_TLS_LIBRARY_MBEDTLS
Using Mbed TLS library.
Definition coap_dtls.h:75
@ COAP_EVENT_DTLS_CLOSED
Triggerred when (D)TLS session closed.
Definition coap_event.h:39
@ COAP_EVENT_DTLS_CONNECTED
Triggered when (D)TLS session connected.
Definition coap_event.h:41
@ COAP_EVENT_DTLS_ERROR
Triggered when (D)TLS error occurs.
Definition coap_event.h:45
#define coap_lock_callback_ret(r, c, func)
Dummy for no thread-safe code.
#define coap_log_debug(...)
Definition coap_debug.h:120
#define coap_log_emerg(...)
Definition coap_debug.h:81
coap_log_t
Logging type.
Definition coap_debug.h:50
coap_log_t coap_dtls_get_log_level(void)
Get the current (D)TLS logging.
Definition coap_notls.c:171
#define coap_dtls_log(level,...)
Logging function.
Definition coap_debug.h:300
void coap_dtls_set_log_level(coap_log_t level)
Sets the (D)TLS logging level to the specified level.
Definition coap_notls.c:166
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log_info(...)
Definition coap_debug.h:108
#define coap_log_warn(...)
Definition coap_debug.h:102
#define coap_log_err(...)
Definition coap_debug.h:96
#define coap_log_crit(...)
Definition coap_debug.h:90
@ COAP_LOG_INFO
Definition coap_debug.h:57
@ COAP_LOG_EMERG
Definition coap_debug.h:51
@ COAP_LOG_NOTICE
Definition coap_debug.h:56
@ COAP_LOG_DEBUG
Definition coap_debug.h:58
@ COAP_LOG_ALERT
Definition coap_debug.h:52
@ COAP_LOG_CRIT
Definition coap_debug.h:53
@ COAP_LOG_ERR
Definition coap_debug.h:54
@ COAP_LOG_WARN
Definition coap_debug.h:55
int coap_netif_available(coap_session_t *session)
Function interface to check whether netif for session is still available.
Definition coap_netif.c:25
int cose_get_hmac_alg_for_hkdf(cose_hkdf_alg_t hkdf_alg, cose_hmac_alg_t *hmac_alg)
cose_hkdf_alg_t
cose_hmac_alg_t
cose_alg_t
@ COSE_HMAC_ALG_HMAC384_384
@ COSE_HMAC_ALG_HMAC256_256
@ COSE_HMAC_ALG_HMAC512_512
@ COSE_ALGORITHM_SHA_256_256
@ COSE_ALGORITHM_SHA_1
@ COSE_ALGORITHM_AES_CCM_16_64_128
@ COSE_ALGORITHM_SHA_512
@ COSE_ALGORITHM_AES_CCM_16_64_256
coap_proto_t
CoAP protocol types.
Definition coap_pdu.h:312
@ COAP_PROTO_DTLS
Definition coap_pdu.h:315
@ COAP_PROTO_TLS
Definition coap_pdu.h:317
@ COAP_PROTO_WSS
Definition coap_pdu.h:319
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).
void coap_session_disconnected_lkd(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
#define COAP_PROTO_NOT_RELIABLE(p)
@ COAP_SESSION_TYPE_CLIENT
client-side
@ COAP_SESSION_STATE_HANDSHAKE
@ COAP_SESSION_STATE_CSM
@ COAP_SESSION_STATE_NONE
coap_binary_t * coap_new_binary(size_t size)
Returns a new binary object with at least size bytes storage allocated.
Definition coap_str.c:77
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...
Definition coap_str.c:110
int coap_dtls_cid_is_supported(void)
Check whether (D)TLS CID is available.
Definition coap_notls.c:86
int coap_dtls_psk_is_supported(void)
Check whether (D)TLS PSK is available.
Definition coap_notls.c:50
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition coap_notls.c:41
int coap_oscore_is_supported(void)
Check whether OSCORE is available.
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition coap_notls.c:36
int coap_dtls_pki_is_supported(void)
Check whether (D)TLS PKI is available.
Definition coap_notls.c:59
int coap_dtls_rpk_is_supported(void)
Check whether (D)TLS RPK is available.
Definition coap_notls.c:77
int coap_dtls_pkcs11_is_supported(void)
Check whether (D)TLS PKCS11 is available.
Definition coap_notls.c:68
#define COAP_UNUSED
Definition libcoap.h:70
coap_address_t remote
remote address and port
Definition coap_io.h:56
CoAP binary data definition with const data.
Definition coap_str.h:64
size_t length
length of binary data
Definition coap_str.h:65
const uint8_t * s
read-only binary data
Definition coap_str.h:66
CoAP binary data definition.
Definition coap_str.h:56
The CoAP stack's global state is stored in a coap_context_t object.
uint8_t testing_cids
Change client's source port every testing_cids.
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 used for defining the Client PSK setup data to be used.
Definition coap_dtls.h:410
uint8_t use_cid
Set to 1 if DTLS Connection ID is to be used.
Definition coap_dtls.h:417
char * client_sni
If not NULL, SNI to use in client TLS setup.
Definition coap_dtls.h:437
coap_dtls_ih_callback_t validate_ih_call_back
Identity Hint check callback function.
Definition coap_dtls.h:433
uint8_t ec_jpake
Set to COAP_DTLS_CPSK_SETUP_VERSION to support this version of the struct.
Definition coap_dtls.h:415
The structure that holds the PKI key information.
Definition coap_dtls.h:279
coap_pki_key_define_t define
for definable type keys
Definition coap_dtls.h:286
union coap_dtls_key_t::@3 key
coap_pki_key_t key_type
key format type
Definition coap_dtls.h:280
The structure used for defining the PKI setup data to be used.
Definition coap_dtls.h:312
void * cn_call_back_arg
Passed in to the CN callback function.
Definition coap_dtls.h:351
uint8_t allow_short_rsa_length
1 if small RSA keysizes are allowed
Definition coap_dtls.h:329
uint8_t cert_chain_validation
1 if to check cert_chain_verify_depth
Definition coap_dtls.h:323
uint8_t allow_bad_md_hash
1 if unsupported MD hashes are allowed
Definition coap_dtls.h:328
uint8_t use_cid
1 if DTLS Connection ID is to be used (Client only, server always enabled) if supported
Definition coap_dtls.h:333
uint8_t check_cert_revocation
1 if revocation checks wanted
Definition coap_dtls.h:325
uint8_t cert_chain_verify_depth
recommended depth is 3
Definition coap_dtls.h:324
uint8_t allow_expired_certs
1 if expired certs are allowed
Definition coap_dtls.h:322
uint8_t verify_peer_cert
Set to COAP_DTLS_PKI_SETUP_VERSION to support this version of the struct.
Definition coap_dtls.h:317
uint8_t allow_self_signed
1 if self-signed certs are allowed.
Definition coap_dtls.h:320
coap_dtls_cn_callback_t validate_cn_call_back
CN check callback function.
Definition coap_dtls.h:350
uint8_t allow_expired_crl
1 if expired crl is allowed
Definition coap_dtls.h:327
uint8_t check_common_ca
1 if peer cert is to be signed by the same CA as the local cert
Definition coap_dtls.h:318
The structure that holds the Server Pre-Shared Key and Identity Hint information.
Definition coap_dtls.h:450
The structure used for defining the Server PSK setup data to be used.
Definition coap_dtls.h:501
coap_dtls_psk_sni_callback_t validate_sni_call_back
SNI check callback function.
Definition coap_dtls.h:530
coap_dtls_id_callback_t validate_id_call_back
Identity check callback function.
Definition coap_dtls.h:522
void * id_call_back_arg
Passed in to the Identity callback function.
Definition coap_dtls.h:523
uint8_t ec_jpake
Set to COAP_DTLS_SPSK_SETUP_VERSION to support this version of the struct.
Definition coap_dtls.h:506
void * sni_call_back_arg
Passed in to the SNI callback function.
Definition coap_dtls.h:531
coap_layer_read_t l_read
coap_layer_write_t l_write
coap_layer_establish_t l_establish
coap_const_char_ptr_t public_cert
define: Public Cert
Definition coap_dtls.h:261
coap_const_char_ptr_t private_key
define: Private Key
Definition coap_dtls.h:262
coap_const_char_ptr_t ca
define: Common CA Certificate
Definition coap_dtls.h:260
size_t public_cert_len
define Public Cert length (if needed)
Definition coap_dtls.h:264
size_t ca_len
define CA Cert length (if needed)
Definition coap_dtls.h:263
coap_pki_define_t private_key_def
define: Private Key type definition
Definition coap_dtls.h:268
size_t private_key_len
define Private Key length (if needed)
Definition coap_dtls.h:265
coap_pki_define_t ca_def
define: Common CA type definition
Definition coap_dtls.h:266
coap_pki_define_t public_cert_def
define: Public Cert type definition
Definition coap_dtls.h:267
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
unsigned int dtls_timeout_count
dtls setup retry counter
coap_endpoint_t * endpoint
session's endpoint
coap_socket_t sock
socket object for the session, if any
coap_session_state_t state
current state of relationship with peer
coap_bin_const_t * client_cid
Contains client CID or NULL.
coap_addr_tuple_t addr_info
remote/local address info
coap_proto_t proto
protocol used
coap_dtls_cpsk_t cpsk_setup_data
client provided PSK initial setup data
size_t mtu
path or CSM mtu (xmt)
uint8_t negotiated_cid
Set for a client if CID negotiated.
int dtls_event
Tracking any (D)TLS events on this session.
void * tls
security parameters
uint16_t max_retransmit
maximum re-transmit count (default 4)
coap_session_type_t type
client or server side socket
coap_context_t * context
session's context
coap_layer_func_t lfunc[COAP_LAYER_LAST]
Layer functions to use.
coap_socket_flags_t flags
1 or more of COAP_SOCKET* flag values
The structure used for returning the underlying (D)TLS library information.
Definition coap_dtls.h:83
uint64_t built_version
(D)TLS Built against Library Version
Definition coap_dtls.h:86
coap_tls_library_t type
Library type.
Definition coap_dtls.h:85
uint64_t version
(D)TLS runtime Library Version
Definition coap_dtls.h:84
const char * s_byte
signed char ptr
Definition coap_str.h:73
const uint8_t * u_byte
unsigned char ptr
Definition coap_str.h:74