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