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