1c87c5fbaSopenharmony_ci/* 2c87c5fbaSopenharmony_ci * coap_tinydtls.c -- Datagram Transport Layer Support for libcoap with tinydtls 3c87c5fbaSopenharmony_ci * 4c87c5fbaSopenharmony_ci * Copyright (C) 2016-2020 Olaf Bergmann <bergmann@tzi.org> 5c87c5fbaSopenharmony_ci * Copyright (C) 2020-2023 Jon Shallow <supjps-libcoap@jpshallow.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_tinydtls.c 15c87c5fbaSopenharmony_ci * @brief TinyDTLS specific handling functions 16c87c5fbaSopenharmony_ci */ 17c87c5fbaSopenharmony_ci 18c87c5fbaSopenharmony_ci#include "coap3/coap_internal.h" 19c87c5fbaSopenharmony_ci 20c87c5fbaSopenharmony_ci#ifdef COAP_WITH_LIBTINYDTLS 21c87c5fbaSopenharmony_ci 22c87c5fbaSopenharmony_ci/* We want TinyDTLS versions of these, not libcoap versions */ 23c87c5fbaSopenharmony_ci#undef PACKAGE_BUGREPORT 24c87c5fbaSopenharmony_ci#undef PACKAGE_NAME 25c87c5fbaSopenharmony_ci#undef PACKAGE_STRING 26c87c5fbaSopenharmony_ci#undef PACKAGE_TARNAME 27c87c5fbaSopenharmony_ci#undef PACKAGE_URL 28c87c5fbaSopenharmony_ci#undef PACKAGE_VERSION 29c87c5fbaSopenharmony_ci 30c87c5fbaSopenharmony_ci#ifndef RIOT_VERSION 31c87c5fbaSopenharmony_ci#include <tinydtls/tinydtls.h> 32c87c5fbaSopenharmony_ci#include <tinydtls/dtls.h> 33c87c5fbaSopenharmony_ci#include <tinydtls/dtls_debug.h> 34c87c5fbaSopenharmony_ci#include <tinydtls/dtls_time.h> 35c87c5fbaSopenharmony_ci#else /* RIOT_VERSION */ 36c87c5fbaSopenharmony_ci#include <tinydtls.h> 37c87c5fbaSopenharmony_ci#include <dtls.h> 38c87c5fbaSopenharmony_ci#include <dtls_debug.h> 39c87c5fbaSopenharmony_ci#include <dtls_time.h> 40c87c5fbaSopenharmony_ci#endif /* RIOT_VERSION */ 41c87c5fbaSopenharmony_ci 42c87c5fbaSopenharmony_citypedef struct coap_tiny_context_t { 43c87c5fbaSopenharmony_ci struct dtls_context_t *dtls_context; 44c87c5fbaSopenharmony_ci coap_context_t *coap_context; 45c87c5fbaSopenharmony_ci#ifdef DTLS_ECC 46c87c5fbaSopenharmony_ci coap_dtls_pki_t setup_data; 47c87c5fbaSopenharmony_ci coap_binary_t *priv_key; 48c87c5fbaSopenharmony_ci coap_binary_t *pub_key; 49c87c5fbaSopenharmony_ci#endif /* DTLS_ECC */ 50c87c5fbaSopenharmony_ci} coap_tiny_context_t; 51c87c5fbaSopenharmony_ci 52c87c5fbaSopenharmony_ci#if ! defined(DTLS_PSK) && ! defined(DTLS_ECC) 53c87c5fbaSopenharmony_ci#error Neither DTLS_PSK or DTLS_ECC defined 54c87c5fbaSopenharmony_ci#endif /* ! DTLS_PSK && ! DTLS_ECC */ 55c87c5fbaSopenharmony_ci 56c87c5fbaSopenharmony_cistatic dtls_tick_t dtls_tick_0 = 0; 57c87c5fbaSopenharmony_cistatic coap_tick_t coap_tick_0 = 0; 58c87c5fbaSopenharmony_ci 59c87c5fbaSopenharmony_ciint 60c87c5fbaSopenharmony_cicoap_dtls_is_supported(void) { 61c87c5fbaSopenharmony_ci return 1; 62c87c5fbaSopenharmony_ci} 63c87c5fbaSopenharmony_ci 64c87c5fbaSopenharmony_ci/* 65c87c5fbaSopenharmony_ci * return 0 failed 66c87c5fbaSopenharmony_ci * 1 passed 67c87c5fbaSopenharmony_ci */ 68c87c5fbaSopenharmony_ciint 69c87c5fbaSopenharmony_cicoap_dtls_psk_is_supported(void) { 70c87c5fbaSopenharmony_ci#ifdef DTLS_PSK 71c87c5fbaSopenharmony_ci return 1; 72c87c5fbaSopenharmony_ci#else /* ! DTLS_PSK */ 73c87c5fbaSopenharmony_ci return 0; 74c87c5fbaSopenharmony_ci#endif /* ! DTLS_PSK */ 75c87c5fbaSopenharmony_ci} 76c87c5fbaSopenharmony_ci 77c87c5fbaSopenharmony_ci/* 78c87c5fbaSopenharmony_ci * return 0 failed 79c87c5fbaSopenharmony_ci * 1 passed 80c87c5fbaSopenharmony_ci */ 81c87c5fbaSopenharmony_ciint 82c87c5fbaSopenharmony_cicoap_dtls_pki_is_supported(void) { 83c87c5fbaSopenharmony_ci return 0; 84c87c5fbaSopenharmony_ci} 85c87c5fbaSopenharmony_ci 86c87c5fbaSopenharmony_ci/* 87c87c5fbaSopenharmony_ci * return 0 failed 88c87c5fbaSopenharmony_ci * 1 passed 89c87c5fbaSopenharmony_ci */ 90c87c5fbaSopenharmony_ciint 91c87c5fbaSopenharmony_cicoap_dtls_pkcs11_is_supported(void) { 92c87c5fbaSopenharmony_ci return 0; 93c87c5fbaSopenharmony_ci} 94c87c5fbaSopenharmony_ci 95c87c5fbaSopenharmony_ci/* 96c87c5fbaSopenharmony_ci * return 0 failed 97c87c5fbaSopenharmony_ci * 1 passed 98c87c5fbaSopenharmony_ci */ 99c87c5fbaSopenharmony_ciint 100c87c5fbaSopenharmony_cicoap_dtls_rpk_is_supported(void) { 101c87c5fbaSopenharmony_ci#ifdef DTLS_ECC 102c87c5fbaSopenharmony_ci return 1; 103c87c5fbaSopenharmony_ci#else /* ! DTLS_ECC */ 104c87c5fbaSopenharmony_ci return 0; 105c87c5fbaSopenharmony_ci#endif /* ! DTLS_ECC */ 106c87c5fbaSopenharmony_ci} 107c87c5fbaSopenharmony_ci 108c87c5fbaSopenharmony_cistatic coap_log_t 109c87c5fbaSopenharmony_cidtls_map_logging(log_t d_level) { 110c87c5fbaSopenharmony_ci /* DTLS_LOG_ERR is missing, so account for the gap */ 111c87c5fbaSopenharmony_ci switch (d_level) { 112c87c5fbaSopenharmony_ci case DTLS_LOG_EMERG: 113c87c5fbaSopenharmony_ci return COAP_LOG_EMERG; 114c87c5fbaSopenharmony_ci break; 115c87c5fbaSopenharmony_ci case DTLS_LOG_ALERT: 116c87c5fbaSopenharmony_ci return COAP_LOG_ALERT; 117c87c5fbaSopenharmony_ci break; 118c87c5fbaSopenharmony_ci case DTLS_LOG_CRIT: 119c87c5fbaSopenharmony_ci return COAP_LOG_CRIT; 120c87c5fbaSopenharmony_ci break; 121c87c5fbaSopenharmony_ci case DTLS_LOG_WARN: 122c87c5fbaSopenharmony_ci return COAP_LOG_WARN; 123c87c5fbaSopenharmony_ci break; 124c87c5fbaSopenharmony_ci case DTLS_LOG_NOTICE: 125c87c5fbaSopenharmony_ci return COAP_LOG_NOTICE; 126c87c5fbaSopenharmony_ci break; 127c87c5fbaSopenharmony_ci case DTLS_LOG_INFO: 128c87c5fbaSopenharmony_ci return COAP_LOG_INFO; 129c87c5fbaSopenharmony_ci break; 130c87c5fbaSopenharmony_ci case DTLS_LOG_DEBUG: 131c87c5fbaSopenharmony_ci default: 132c87c5fbaSopenharmony_ci return COAP_LOG_DEBUG; 133c87c5fbaSopenharmony_ci break; 134c87c5fbaSopenharmony_ci } 135c87c5fbaSopenharmony_ci return COAP_LOG_DEBUG; 136c87c5fbaSopenharmony_ci} 137c87c5fbaSopenharmony_ci#ifdef HAVE_DTLS_SET_LOG_HANDLER 138c87c5fbaSopenharmony_ci/* Valid after TinyDTLS submodule has been updated */ 139c87c5fbaSopenharmony_cistatic void 140c87c5fbaSopenharmony_cidtls_logging(log_t d_level, const char *message) { 141c87c5fbaSopenharmony_ci coap_log_t c_level = dtls_map_logging(d_level); 142c87c5fbaSopenharmony_ci 143c87c5fbaSopenharmony_ci coap_dtls_log(c_level, "%s", message); 144c87c5fbaSopenharmony_ci} 145c87c5fbaSopenharmony_ci#endif /* HAVE_DTLS_SET_LOG_HANDLER */ 146c87c5fbaSopenharmony_ci 147c87c5fbaSopenharmony_civoid 148c87c5fbaSopenharmony_cicoap_dtls_startup(void) { 149c87c5fbaSopenharmony_ci dtls_init(); 150c87c5fbaSopenharmony_ci dtls_ticks(&dtls_tick_0); 151c87c5fbaSopenharmony_ci coap_ticks(&coap_tick_0); 152c87c5fbaSopenharmony_ci#ifdef HAVE_DTLS_SET_LOG_HANDLER 153c87c5fbaSopenharmony_ci /* Valid after TinyDTLS submodule has been updated */ 154c87c5fbaSopenharmony_ci dtls_set_log_handler(dtls_logging); 155c87c5fbaSopenharmony_ci#endif /* HAVE_DTLS_SET_LOG_HANDLER */ 156c87c5fbaSopenharmony_ci coap_dtls_set_log_level(COAP_LOG_EMERG); 157c87c5fbaSopenharmony_ci} 158c87c5fbaSopenharmony_ci 159c87c5fbaSopenharmony_civoid 160c87c5fbaSopenharmony_cicoap_dtls_shutdown(void) { 161c87c5fbaSopenharmony_ci coap_dtls_set_log_level(COAP_LOG_EMERG); 162c87c5fbaSopenharmony_ci} 163c87c5fbaSopenharmony_ci 164c87c5fbaSopenharmony_civoid * 165c87c5fbaSopenharmony_cicoap_dtls_get_tls(const coap_session_t *c_session, 166c87c5fbaSopenharmony_ci coap_tls_library_t *tls_lib) { 167c87c5fbaSopenharmony_ci if (tls_lib) 168c87c5fbaSopenharmony_ci *tls_lib = COAP_TLS_LIBRARY_TINYDTLS; 169c87c5fbaSopenharmony_ci if (c_session && c_session->context && c_session->context->dtls_context) { 170c87c5fbaSopenharmony_ci const coap_tiny_context_t *t_context = 171c87c5fbaSopenharmony_ci (const coap_tiny_context_t *)c_session->context->dtls_context; 172c87c5fbaSopenharmony_ci 173c87c5fbaSopenharmony_ci return t_context->dtls_context; 174c87c5fbaSopenharmony_ci } 175c87c5fbaSopenharmony_ci return NULL; 176c87c5fbaSopenharmony_ci} 177c87c5fbaSopenharmony_ci 178c87c5fbaSopenharmony_civoid 179c87c5fbaSopenharmony_cicoap_dtls_set_log_level(coap_log_t c_level) { 180c87c5fbaSopenharmony_ci log_t d_level; 181c87c5fbaSopenharmony_ci 182c87c5fbaSopenharmony_ci /* DTLS_LOG_ERR is missing, so account for the gap */ 183c87c5fbaSopenharmony_ci switch (c_level) { 184c87c5fbaSopenharmony_ci case COAP_LOG_EMERG: 185c87c5fbaSopenharmony_ci d_level = DTLS_LOG_EMERG; 186c87c5fbaSopenharmony_ci break; 187c87c5fbaSopenharmony_ci case COAP_LOG_ALERT: 188c87c5fbaSopenharmony_ci d_level = DTLS_LOG_ALERT; 189c87c5fbaSopenharmony_ci break; 190c87c5fbaSopenharmony_ci case COAP_LOG_CRIT: 191c87c5fbaSopenharmony_ci case COAP_LOG_ERR: 192c87c5fbaSopenharmony_ci d_level = DTLS_LOG_CRIT; 193c87c5fbaSopenharmony_ci break; 194c87c5fbaSopenharmony_ci case COAP_LOG_WARN: 195c87c5fbaSopenharmony_ci d_level = DTLS_LOG_WARN; 196c87c5fbaSopenharmony_ci break; 197c87c5fbaSopenharmony_ci case COAP_LOG_NOTICE: 198c87c5fbaSopenharmony_ci d_level = DTLS_LOG_NOTICE; 199c87c5fbaSopenharmony_ci break; 200c87c5fbaSopenharmony_ci case COAP_LOG_INFO: 201c87c5fbaSopenharmony_ci d_level = DTLS_LOG_INFO; 202c87c5fbaSopenharmony_ci break; 203c87c5fbaSopenharmony_ci case COAP_LOG_DEBUG: 204c87c5fbaSopenharmony_ci case COAP_LOG_OSCORE: 205c87c5fbaSopenharmony_ci case COAP_LOG_DTLS_BASE: 206c87c5fbaSopenharmony_ci default: 207c87c5fbaSopenharmony_ci d_level = DTLS_LOG_DEBUG; 208c87c5fbaSopenharmony_ci break; 209c87c5fbaSopenharmony_ci } 210c87c5fbaSopenharmony_ci dtls_set_log_level(d_level); 211c87c5fbaSopenharmony_ci} 212c87c5fbaSopenharmony_ci 213c87c5fbaSopenharmony_cicoap_log_t 214c87c5fbaSopenharmony_cicoap_dtls_get_log_level(void) { 215c87c5fbaSopenharmony_ci log_t d_level = dtls_get_log_level(); 216c87c5fbaSopenharmony_ci 217c87c5fbaSopenharmony_ci return dtls_map_logging(d_level); 218c87c5fbaSopenharmony_ci} 219c87c5fbaSopenharmony_ci 220c87c5fbaSopenharmony_cistatic void 221c87c5fbaSopenharmony_ciget_session_addr(const session_t *s, coap_address_t *a) { 222c87c5fbaSopenharmony_ci#if defined(WITH_CONTIKI) || defined(WITH_LWIP) 223c87c5fbaSopenharmony_ci a->addr = s->addr; 224c87c5fbaSopenharmony_ci a->port = s->port; 225c87c5fbaSopenharmony_ci#elif defined(WITH_RIOT_SOCK) 226c87c5fbaSopenharmony_ci if (s->addr.family == AF_INET6) { 227c87c5fbaSopenharmony_ci a->size = (socklen_t)sizeof(a->addr.sin6); 228c87c5fbaSopenharmony_ci a->addr.sa.sa_family = s->addr.family; 229c87c5fbaSopenharmony_ci memcpy(&a->addr.sin6.sin6_addr, &s->addr.ipv6, 230c87c5fbaSopenharmony_ci sizeof(a->addr.sin6.sin6_addr)); 231c87c5fbaSopenharmony_ci a->addr.sin6.sin6_port = s->addr.port; 232c87c5fbaSopenharmony_ci#ifdef SOCK_HAS_IPV4 233c87c5fbaSopenharmony_ci } else if (s->addr.family == AF_INET) { 234c87c5fbaSopenharmony_ci a->addr.sa.sa_family = s->addr.family; 235c87c5fbaSopenharmony_ci a->size = (socklen_t)sizeof(a->addr.sin); 236c87c5fbaSopenharmony_ci memcpy(&a->addr.sin.sin_addr, &s->addr.ipv4, sizeof(a->addr.sin.sin_addr)); 237c87c5fbaSopenharmony_ci a->addr.sin.sin_port = s->addr.port; 238c87c5fbaSopenharmony_ci#endif /* SOCK_HAS_IPV4 */ 239c87c5fbaSopenharmony_ci } 240c87c5fbaSopenharmony_ci#else /* ! WITH_CONTIKI && ! WITH_LWIP && ! WITH_RIOT_SOCK */ 241c87c5fbaSopenharmony_ci if (s->addr.sa.sa_family == AF_INET6) { 242c87c5fbaSopenharmony_ci a->size = (socklen_t)sizeof(a->addr.sin6); 243c87c5fbaSopenharmony_ci a->addr.sin6 = s->addr.sin6; 244c87c5fbaSopenharmony_ci } else if (s->addr.sa.sa_family == AF_INET) { 245c87c5fbaSopenharmony_ci a->size = (socklen_t)sizeof(a->addr.sin); 246c87c5fbaSopenharmony_ci a->addr.sin = s->addr.sin; 247c87c5fbaSopenharmony_ci } else { 248c87c5fbaSopenharmony_ci a->size = (socklen_t)s->size; 249c87c5fbaSopenharmony_ci a->addr.sa = s->addr.sa; 250c87c5fbaSopenharmony_ci } 251c87c5fbaSopenharmony_ci#endif /* ! WITH_CONTIKI && ! WITH_LWIP && ! WITH_RIOT_SOCK */ 252c87c5fbaSopenharmony_ci} 253c87c5fbaSopenharmony_ci 254c87c5fbaSopenharmony_cistatic void 255c87c5fbaSopenharmony_ciput_session_addr(const coap_address_t *a, session_t *s) { 256c87c5fbaSopenharmony_ci#if defined(WITH_CONTIKI) || defined(WITH_LWIP) 257c87c5fbaSopenharmony_ci s->size = (unsigned char)sizeof(s->addr); 258c87c5fbaSopenharmony_ci s->addr = a->addr; 259c87c5fbaSopenharmony_ci s->port = a->port; 260c87c5fbaSopenharmony_ci#elif defined(WITH_RIOT_SOCK) 261c87c5fbaSopenharmony_ci if (a->addr.sa.sa_family == AF_INET6) { 262c87c5fbaSopenharmony_ci s->size = (socklen_t)sizeof(s->addr.ipv6); 263c87c5fbaSopenharmony_ci s->addr.family = a->addr.sa.sa_family; 264c87c5fbaSopenharmony_ci memcpy(&s->addr.ipv6, &a->addr.sin6.sin6_addr, 265c87c5fbaSopenharmony_ci sizeof(s->addr.ipv6)); 266c87c5fbaSopenharmony_ci s->addr.port = a->addr.sin6.sin6_port; 267c87c5fbaSopenharmony_ci#ifdef SOCK_HAS_IPV4 268c87c5fbaSopenharmony_ci } else if (a->addr.sa.sa_family == AF_INET) { 269c87c5fbaSopenharmony_ci s->size = (socklen_t)sizeof(s->addr.ipv4); 270c87c5fbaSopenharmony_ci s->addr.family = a->addr.sa.sa_family; 271c87c5fbaSopenharmony_ci memcpy(&a->addr.ipv4, &s->addr.sin.sin_addr, sizeof(a->addr.ipv4)); 272c87c5fbaSopenharmony_ci s->addr.port = a->addr.sin.sin_port; 273c87c5fbaSopenharmony_ci#endif /* SOCK_HAS_IPV4 */ 274c87c5fbaSopenharmony_ci } 275c87c5fbaSopenharmony_ci#else /* ! WITH_CONTIKI && ! WITH_LWIP && ! WITH_RIOT_SOCK */ 276c87c5fbaSopenharmony_ci if (a->addr.sa.sa_family == AF_INET6) { 277c87c5fbaSopenharmony_ci s->size = (socklen_t)sizeof(s->addr.sin6); 278c87c5fbaSopenharmony_ci s->addr.sin6 = a->addr.sin6; 279c87c5fbaSopenharmony_ci } else if (a->addr.sa.sa_family == AF_INET) { 280c87c5fbaSopenharmony_ci s->size = (socklen_t)sizeof(s->addr.sin); 281c87c5fbaSopenharmony_ci s->addr.sin = a->addr.sin; 282c87c5fbaSopenharmony_ci } else { 283c87c5fbaSopenharmony_ci s->size = (socklen_t)a->size; 284c87c5fbaSopenharmony_ci s->addr.sa = a->addr.sa; 285c87c5fbaSopenharmony_ci } 286c87c5fbaSopenharmony_ci#endif /* ! WITH_CONTIKI && ! WITH_LWIP && ! WITH_RIOT_SOCK */ 287c87c5fbaSopenharmony_ci} 288c87c5fbaSopenharmony_ci 289c87c5fbaSopenharmony_cistatic int 290c87c5fbaSopenharmony_cidtls_send_to_peer(struct dtls_context_t *dtls_context, 291c87c5fbaSopenharmony_ci session_t *dtls_session, uint8 *data, size_t len) { 292c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = 293c87c5fbaSopenharmony_ci (coap_tiny_context_t *)dtls_get_app_data(dtls_context); 294c87c5fbaSopenharmony_ci coap_context_t *coap_context = t_context ? t_context->coap_context : NULL; 295c87c5fbaSopenharmony_ci coap_session_t *coap_session; 296c87c5fbaSopenharmony_ci coap_address_t remote_addr; 297c87c5fbaSopenharmony_ci 298c87c5fbaSopenharmony_ci assert(coap_context); 299c87c5fbaSopenharmony_ci get_session_addr(dtls_session, &remote_addr); 300c87c5fbaSopenharmony_ci coap_session = coap_session_get_by_peer(coap_context, &remote_addr, dtls_session->ifindex); 301c87c5fbaSopenharmony_ci if (!coap_session) { 302c87c5fbaSopenharmony_ci coap_log_warn("dtls_send_to_peer: cannot find local interface\n"); 303c87c5fbaSopenharmony_ci return -3; 304c87c5fbaSopenharmony_ci } 305c87c5fbaSopenharmony_ci return (int)coap_session->sock.lfunc[COAP_LAYER_TLS].l_write(coap_session, 306c87c5fbaSopenharmony_ci data, len); 307c87c5fbaSopenharmony_ci} 308c87c5fbaSopenharmony_ci 309c87c5fbaSopenharmony_cistatic int 310c87c5fbaSopenharmony_cidtls_application_data(struct dtls_context_t *dtls_context, 311c87c5fbaSopenharmony_ci session_t *dtls_session, uint8 *data, size_t len) { 312c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = 313c87c5fbaSopenharmony_ci (coap_tiny_context_t *)dtls_get_app_data(dtls_context); 314c87c5fbaSopenharmony_ci coap_context_t *coap_context = t_context ? t_context->coap_context : NULL; 315c87c5fbaSopenharmony_ci coap_session_t *coap_session; 316c87c5fbaSopenharmony_ci coap_address_t remote_addr; 317c87c5fbaSopenharmony_ci 318c87c5fbaSopenharmony_ci assert(coap_context); 319c87c5fbaSopenharmony_ci get_session_addr(dtls_session, &remote_addr); 320c87c5fbaSopenharmony_ci coap_session = coap_session_get_by_peer(coap_context, &remote_addr, dtls_session->ifindex); 321c87c5fbaSopenharmony_ci if (!coap_session) { 322c87c5fbaSopenharmony_ci coap_log_debug("dropped message that was received on invalid interface\n"); 323c87c5fbaSopenharmony_ci return -1; 324c87c5fbaSopenharmony_ci } 325c87c5fbaSopenharmony_ci 326c87c5fbaSopenharmony_ci return coap_handle_dgram(coap_context, coap_session, data, len); 327c87c5fbaSopenharmony_ci} 328c87c5fbaSopenharmony_ci 329c87c5fbaSopenharmony_cistatic int coap_event_dtls = 0; 330c87c5fbaSopenharmony_ci 331c87c5fbaSopenharmony_cistatic int 332c87c5fbaSopenharmony_cidtls_event(struct dtls_context_t *dtls_context, 333c87c5fbaSopenharmony_ci session_t *dtls_session, 334c87c5fbaSopenharmony_ci dtls_alert_level_t level, 335c87c5fbaSopenharmony_ci uint16_t code) { 336c87c5fbaSopenharmony_ci (void)dtls_context; 337c87c5fbaSopenharmony_ci (void)dtls_session; 338c87c5fbaSopenharmony_ci 339c87c5fbaSopenharmony_ci if (level == DTLS_ALERT_LEVEL_FATAL) 340c87c5fbaSopenharmony_ci coap_event_dtls = COAP_EVENT_DTLS_ERROR; 341c87c5fbaSopenharmony_ci 342c87c5fbaSopenharmony_ci /* handle DTLS events */ 343c87c5fbaSopenharmony_ci switch (code) { 344c87c5fbaSopenharmony_ci case DTLS_ALERT_CLOSE_NOTIFY: { 345c87c5fbaSopenharmony_ci coap_event_dtls = COAP_EVENT_DTLS_CLOSED; 346c87c5fbaSopenharmony_ci break; 347c87c5fbaSopenharmony_ci } 348c87c5fbaSopenharmony_ci case DTLS_EVENT_CONNECTED: { 349c87c5fbaSopenharmony_ci coap_event_dtls = COAP_EVENT_DTLS_CONNECTED; 350c87c5fbaSopenharmony_ci break; 351c87c5fbaSopenharmony_ci } 352c87c5fbaSopenharmony_ci#ifdef DTLS_EVENT_RENEGOTIATE 353c87c5fbaSopenharmony_ci case DTLS_EVENT_RENEGOTIATE: { 354c87c5fbaSopenharmony_ci coap_event_dtls = COAP_EVENT_DTLS_RENEGOTIATE; 355c87c5fbaSopenharmony_ci break; 356c87c5fbaSopenharmony_ci } 357c87c5fbaSopenharmony_ci#endif 358c87c5fbaSopenharmony_ci default: 359c87c5fbaSopenharmony_ci ; 360c87c5fbaSopenharmony_ci } 361c87c5fbaSopenharmony_ci 362c87c5fbaSopenharmony_ci return 0; 363c87c5fbaSopenharmony_ci} 364c87c5fbaSopenharmony_ci 365c87c5fbaSopenharmony_ci#ifdef DTLS_PSK 366c87c5fbaSopenharmony_ci/* This function is the "key store" for tinyDTLS. It is called to 367c87c5fbaSopenharmony_ci * retrieve a key for the given identity within this particular 368c87c5fbaSopenharmony_ci * session. */ 369c87c5fbaSopenharmony_cistatic int 370c87c5fbaSopenharmony_ciget_psk_info(struct dtls_context_t *dtls_context, 371c87c5fbaSopenharmony_ci const session_t *dtls_session, 372c87c5fbaSopenharmony_ci dtls_credentials_type_t type, 373c87c5fbaSopenharmony_ci const uint8_t *id, size_t id_len, 374c87c5fbaSopenharmony_ci unsigned char *result, size_t result_length) { 375c87c5fbaSopenharmony_ci 376c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = 377c87c5fbaSopenharmony_ci (coap_tiny_context_t *)dtls_get_app_data(dtls_context); 378c87c5fbaSopenharmony_ci coap_context_t *coap_context = t_context ? t_context->coap_context : NULL; 379c87c5fbaSopenharmony_ci coap_session_t *coap_session; 380c87c5fbaSopenharmony_ci int fatal_error = DTLS_ALERT_INTERNAL_ERROR; 381c87c5fbaSopenharmony_ci coap_address_t remote_addr; 382c87c5fbaSopenharmony_ci#if COAP_CLIENT_SUPPORT 383c87c5fbaSopenharmony_ci coap_dtls_cpsk_t *setup_cdata; 384c87c5fbaSopenharmony_ci const coap_bin_const_t *psk_identity; 385c87c5fbaSopenharmony_ci const coap_dtls_cpsk_info_t *cpsk_info; 386c87c5fbaSopenharmony_ci#endif /* COAP_CLIENT_SUPPORT */ 387c87c5fbaSopenharmony_ci const coap_bin_const_t *psk_key; 388c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 389c87c5fbaSopenharmony_ci coap_dtls_spsk_t *setup_sdata; 390c87c5fbaSopenharmony_ci const coap_bin_const_t *psk_hint; 391c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 392c87c5fbaSopenharmony_ci 393c87c5fbaSopenharmony_ci assert(coap_context); 394c87c5fbaSopenharmony_ci get_session_addr(dtls_session, &remote_addr); 395c87c5fbaSopenharmony_ci coap_session = coap_session_get_by_peer(coap_context, &remote_addr, dtls_session->ifindex); 396c87c5fbaSopenharmony_ci if (!coap_session) { 397c87c5fbaSopenharmony_ci coap_log_debug("cannot get PSK, session not found\n"); 398c87c5fbaSopenharmony_ci goto error; 399c87c5fbaSopenharmony_ci } 400c87c5fbaSopenharmony_ci 401c87c5fbaSopenharmony_ci switch (type) { 402c87c5fbaSopenharmony_ci case DTLS_PSK_IDENTITY: 403c87c5fbaSopenharmony_ci 404c87c5fbaSopenharmony_ci#if COAP_CLIENT_SUPPORT 405c87c5fbaSopenharmony_ci if (coap_session->type != COAP_SESSION_TYPE_CLIENT) 406c87c5fbaSopenharmony_ci goto error; 407c87c5fbaSopenharmony_ci 408c87c5fbaSopenharmony_ci setup_cdata = &coap_session->cpsk_setup_data; 409c87c5fbaSopenharmony_ci 410c87c5fbaSopenharmony_ci coap_bin_const_t temp; 411c87c5fbaSopenharmony_ci temp.s = id; 412c87c5fbaSopenharmony_ci temp.length = id_len; 413c87c5fbaSopenharmony_ci coap_session_refresh_psk_hint(coap_session, &temp); 414c87c5fbaSopenharmony_ci 415c87c5fbaSopenharmony_ci coap_log_debug("got psk_identity_hint: '%.*s'\n", (int)id_len, 416c87c5fbaSopenharmony_ci id ? (const char *)id : ""); 417c87c5fbaSopenharmony_ci 418c87c5fbaSopenharmony_ci if (setup_cdata->validate_ih_call_back) { 419c87c5fbaSopenharmony_ci coap_str_const_t lhint; 420c87c5fbaSopenharmony_ci 421c87c5fbaSopenharmony_ci lhint.length = id_len; 422c87c5fbaSopenharmony_ci lhint.s = id; 423c87c5fbaSopenharmony_ci cpsk_info = 424c87c5fbaSopenharmony_ci setup_cdata->validate_ih_call_back(&lhint, 425c87c5fbaSopenharmony_ci coap_session, 426c87c5fbaSopenharmony_ci setup_cdata->ih_call_back_arg); 427c87c5fbaSopenharmony_ci if (cpsk_info) { 428c87c5fbaSopenharmony_ci psk_identity = &cpsk_info->identity; 429c87c5fbaSopenharmony_ci coap_session_refresh_psk_identity(coap_session, &cpsk_info->identity); 430c87c5fbaSopenharmony_ci coap_session_refresh_psk_key(coap_session, &cpsk_info->key); 431c87c5fbaSopenharmony_ci } else { 432c87c5fbaSopenharmony_ci psk_identity = NULL; 433c87c5fbaSopenharmony_ci } 434c87c5fbaSopenharmony_ci } else { 435c87c5fbaSopenharmony_ci psk_identity = coap_get_session_client_psk_identity(coap_session); 436c87c5fbaSopenharmony_ci } 437c87c5fbaSopenharmony_ci if (psk_identity == NULL) { 438c87c5fbaSopenharmony_ci coap_log_warn("no PSK identity given\n"); 439c87c5fbaSopenharmony_ci fatal_error = DTLS_ALERT_CLOSE_NOTIFY; 440c87c5fbaSopenharmony_ci goto error; 441c87c5fbaSopenharmony_ci } 442c87c5fbaSopenharmony_ci if (psk_identity->length > result_length) { 443c87c5fbaSopenharmony_ci coap_log_warn("psk_identity too large, truncated to %zd bytes\n", 444c87c5fbaSopenharmony_ci result_length); 445c87c5fbaSopenharmony_ci } else { 446c87c5fbaSopenharmony_ci /* Reduce to match */ 447c87c5fbaSopenharmony_ci result_length = psk_identity->length; 448c87c5fbaSopenharmony_ci } 449c87c5fbaSopenharmony_ci memcpy(result, psk_identity->s, result_length); 450c87c5fbaSopenharmony_ci return result_length; 451c87c5fbaSopenharmony_ci#else /* ! COAP_CLIENT_SUPPORT */ 452c87c5fbaSopenharmony_ci return 0; 453c87c5fbaSopenharmony_ci#endif /* ! COAP_CLIENT_SUPPORT */ 454c87c5fbaSopenharmony_ci 455c87c5fbaSopenharmony_ci case DTLS_PSK_KEY: 456c87c5fbaSopenharmony_ci#if COAP_CLIENT_SUPPORT 457c87c5fbaSopenharmony_ci if (coap_session->type == COAP_SESSION_TYPE_CLIENT) { 458c87c5fbaSopenharmony_ci psk_key = coap_get_session_client_psk_key(coap_session); 459c87c5fbaSopenharmony_ci if (psk_key == NULL) { 460c87c5fbaSopenharmony_ci coap_log_warn("no PSK key given\n"); 461c87c5fbaSopenharmony_ci fatal_error = DTLS_ALERT_CLOSE_NOTIFY; 462c87c5fbaSopenharmony_ci goto error; 463c87c5fbaSopenharmony_ci } 464c87c5fbaSopenharmony_ci if (psk_key->length > result_length) { 465c87c5fbaSopenharmony_ci coap_log_warn("psk_key too large, truncated to %zd bytes\n", 466c87c5fbaSopenharmony_ci result_length); 467c87c5fbaSopenharmony_ci } else { 468c87c5fbaSopenharmony_ci /* Reduce to match */ 469c87c5fbaSopenharmony_ci result_length = psk_key->length; 470c87c5fbaSopenharmony_ci } 471c87c5fbaSopenharmony_ci memcpy(result, psk_key->s, result_length); 472c87c5fbaSopenharmony_ci return result_length; 473c87c5fbaSopenharmony_ci } 474c87c5fbaSopenharmony_ci#endif /* COAP_CLIENT_SUPPORT */ 475c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 476c87c5fbaSopenharmony_ci if (coap_session->type != COAP_SESSION_TYPE_CLIENT) { 477c87c5fbaSopenharmony_ci coap_bin_const_t lidentity; 478c87c5fbaSopenharmony_ci 479c87c5fbaSopenharmony_ci lidentity.length = id ? id_len : 0; 480c87c5fbaSopenharmony_ci lidentity.s = id ? (const uint8_t *)id : (const uint8_t *)""; 481c87c5fbaSopenharmony_ci setup_sdata = &coap_session->context->spsk_setup_data; 482c87c5fbaSopenharmony_ci 483c87c5fbaSopenharmony_ci /* Track the Identity being used */ 484c87c5fbaSopenharmony_ci coap_session_refresh_psk_identity(coap_session, &lidentity); 485c87c5fbaSopenharmony_ci 486c87c5fbaSopenharmony_ci coap_log_debug("got psk_identity: '%.*s'\n", 487c87c5fbaSopenharmony_ci (int)lidentity.length, lidentity.s); 488c87c5fbaSopenharmony_ci 489c87c5fbaSopenharmony_ci if (setup_sdata->validate_id_call_back) { 490c87c5fbaSopenharmony_ci psk_key = 491c87c5fbaSopenharmony_ci setup_sdata->validate_id_call_back(&lidentity, 492c87c5fbaSopenharmony_ci coap_session, 493c87c5fbaSopenharmony_ci setup_sdata->id_call_back_arg); 494c87c5fbaSopenharmony_ci } else { 495c87c5fbaSopenharmony_ci psk_key = coap_get_session_server_psk_key(coap_session); 496c87c5fbaSopenharmony_ci } 497c87c5fbaSopenharmony_ci 498c87c5fbaSopenharmony_ci if (psk_key == NULL) { 499c87c5fbaSopenharmony_ci coap_log_warn("no PSK key given\n"); 500c87c5fbaSopenharmony_ci return 0; 501c87c5fbaSopenharmony_ci } 502c87c5fbaSopenharmony_ci if (setup_sdata->validate_id_call_back) 503c87c5fbaSopenharmony_ci coap_session_refresh_psk_key(coap_session, psk_key); 504c87c5fbaSopenharmony_ci if (psk_key->length > result_length) { 505c87c5fbaSopenharmony_ci coap_log_warn("psk_key too large, truncated to %zd bytes\n", 506c87c5fbaSopenharmony_ci result_length); 507c87c5fbaSopenharmony_ci } else { 508c87c5fbaSopenharmony_ci /* Reduce to match */ 509c87c5fbaSopenharmony_ci result_length = psk_key->length; 510c87c5fbaSopenharmony_ci } 511c87c5fbaSopenharmony_ci memcpy(result, psk_key->s, result_length); 512c87c5fbaSopenharmony_ci return result_length; 513c87c5fbaSopenharmony_ci } 514c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 515c87c5fbaSopenharmony_ci return 0; 516c87c5fbaSopenharmony_ci 517c87c5fbaSopenharmony_ci case DTLS_PSK_HINT: 518c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 519c87c5fbaSopenharmony_ci psk_hint = coap_get_session_server_psk_hint(coap_session); 520c87c5fbaSopenharmony_ci if (psk_hint == NULL) 521c87c5fbaSopenharmony_ci return 0; 522c87c5fbaSopenharmony_ci if (psk_hint->length > result_length) { 523c87c5fbaSopenharmony_ci coap_log_warn("psk_hint too large, truncated to %zd bytes\n", 524c87c5fbaSopenharmony_ci result_length); 525c87c5fbaSopenharmony_ci } else { 526c87c5fbaSopenharmony_ci /* Reduce to match */ 527c87c5fbaSopenharmony_ci result_length = psk_hint->length; 528c87c5fbaSopenharmony_ci } 529c87c5fbaSopenharmony_ci memcpy(result, psk_hint->s, result_length); 530c87c5fbaSopenharmony_ci return result_length; 531c87c5fbaSopenharmony_ci#else /* COAP_SERVER_SUPPORT */ 532c87c5fbaSopenharmony_ci return 0; 533c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 534c87c5fbaSopenharmony_ci 535c87c5fbaSopenharmony_ci default: 536c87c5fbaSopenharmony_ci coap_log_warn("unsupported request type: %d\n", type); 537c87c5fbaSopenharmony_ci } 538c87c5fbaSopenharmony_ci 539c87c5fbaSopenharmony_cierror: 540c87c5fbaSopenharmony_ci return dtls_alert_fatal_create(fatal_error); 541c87c5fbaSopenharmony_ci} 542c87c5fbaSopenharmony_ci#endif /* DTLS_PSK */ 543c87c5fbaSopenharmony_ci 544c87c5fbaSopenharmony_ci#ifdef DTLS_ECC 545c87c5fbaSopenharmony_cistatic int 546c87c5fbaSopenharmony_ciget_ecdsa_key(struct dtls_context_t *dtls_context, 547c87c5fbaSopenharmony_ci const session_t *dtls_session COAP_UNUSED, 548c87c5fbaSopenharmony_ci const dtls_ecdsa_key_t **result) { 549c87c5fbaSopenharmony_ci static dtls_ecdsa_key_t ecdsa_key; 550c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = 551c87c5fbaSopenharmony_ci (coap_tiny_context_t *)dtls_get_app_data(dtls_context); 552c87c5fbaSopenharmony_ci 553c87c5fbaSopenharmony_ci ecdsa_key.curve = DTLS_ECDH_CURVE_SECP256R1; 554c87c5fbaSopenharmony_ci ecdsa_key.priv_key = t_context->priv_key->s; 555c87c5fbaSopenharmony_ci ecdsa_key.pub_key_x = t_context->pub_key->s; 556c87c5fbaSopenharmony_ci ecdsa_key.pub_key_y = &t_context->pub_key->s[DTLS_EC_KEY_SIZE]; 557c87c5fbaSopenharmony_ci 558c87c5fbaSopenharmony_ci *result = &ecdsa_key; 559c87c5fbaSopenharmony_ci return 0; 560c87c5fbaSopenharmony_ci} 561c87c5fbaSopenharmony_ci 562c87c5fbaSopenharmony_ci/* first part of Raw public key, the is the start of the Subject Public Key */ 563c87c5fbaSopenharmony_cistatic const unsigned char cert_asn1_header[] = { 564c87c5fbaSopenharmony_ci 0x30, 0x59, /* SEQUENCE, length 89 bytes */ 565c87c5fbaSopenharmony_ci 0x30, 0x13, /* SEQUENCE, length 19 bytes */ 566c87c5fbaSopenharmony_ci 0x06, 0x07, /* OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) */ 567c87c5fbaSopenharmony_ci 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 568c87c5fbaSopenharmony_ci 0x06, 0x08, /* OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7) */ 569c87c5fbaSopenharmony_ci 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 570c87c5fbaSopenharmony_ci 0x03, 0x42, 0x00, /* BIT STRING, length 66 bytes, 0 bits unused */ 571c87c5fbaSopenharmony_ci 0x04 /* uncompressed, followed by the r and s values of the public key */ 572c87c5fbaSopenharmony_ci}; 573c87c5fbaSopenharmony_ci#define DTLS_CE_LENGTH (sizeof(cert_asn1_header) + key_size + key_size) 574c87c5fbaSopenharmony_ci 575c87c5fbaSopenharmony_cistatic int 576c87c5fbaSopenharmony_civerify_ecdsa_key(struct dtls_context_t *dtls_context COAP_UNUSED, 577c87c5fbaSopenharmony_ci const session_t *dtls_session COAP_UNUSED, 578c87c5fbaSopenharmony_ci const uint8_t *other_pub_x, 579c87c5fbaSopenharmony_ci const uint8_t *other_pub_y, 580c87c5fbaSopenharmony_ci size_t key_size) { 581c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = 582c87c5fbaSopenharmony_ci (coap_tiny_context_t *)dtls_get_app_data(dtls_context); 583c87c5fbaSopenharmony_ci if (t_context && t_context->setup_data.validate_cn_call_back) { 584c87c5fbaSopenharmony_ci /* Need to build asn.1 certificate - code taken from tinydtls */ 585c87c5fbaSopenharmony_ci uint8 *p; 586c87c5fbaSopenharmony_ci uint8 buf[DTLS_CE_LENGTH]; 587c87c5fbaSopenharmony_ci coap_session_t *c_session; 588c87c5fbaSopenharmony_ci coap_address_t remote_addr; 589c87c5fbaSopenharmony_ci 590c87c5fbaSopenharmony_ci /* Certificate 591c87c5fbaSopenharmony_ci * 592c87c5fbaSopenharmony_ci * Start message construction at beginning of buffer. */ 593c87c5fbaSopenharmony_ci p = buf; 594c87c5fbaSopenharmony_ci 595c87c5fbaSopenharmony_ci memcpy(p, &cert_asn1_header, sizeof(cert_asn1_header)); 596c87c5fbaSopenharmony_ci p += sizeof(cert_asn1_header); 597c87c5fbaSopenharmony_ci 598c87c5fbaSopenharmony_ci memcpy(p, other_pub_x, key_size); 599c87c5fbaSopenharmony_ci p += key_size; 600c87c5fbaSopenharmony_ci 601c87c5fbaSopenharmony_ci memcpy(p, other_pub_y, key_size); 602c87c5fbaSopenharmony_ci p += key_size; 603c87c5fbaSopenharmony_ci 604c87c5fbaSopenharmony_ci assert(p <= (buf + sizeof(buf))); 605c87c5fbaSopenharmony_ci 606c87c5fbaSopenharmony_ci get_session_addr(dtls_session, &remote_addr); 607c87c5fbaSopenharmony_ci c_session = coap_session_get_by_peer(t_context->coap_context, 608c87c5fbaSopenharmony_ci &remote_addr, dtls_session->ifindex); 609c87c5fbaSopenharmony_ci if (!c_session) 610c87c5fbaSopenharmony_ci return -3; 611c87c5fbaSopenharmony_ci if (!t_context->setup_data.validate_cn_call_back(COAP_DTLS_RPK_CERT_CN, 612c87c5fbaSopenharmony_ci buf, p-buf, c_session, 0, 1, t_context->setup_data.cn_call_back_arg)) { 613c87c5fbaSopenharmony_ci return -1; 614c87c5fbaSopenharmony_ci } 615c87c5fbaSopenharmony_ci } 616c87c5fbaSopenharmony_ci return 0; 617c87c5fbaSopenharmony_ci} 618c87c5fbaSopenharmony_cistatic dtls_handler_t ec_cb = { 619c87c5fbaSopenharmony_ci .write = dtls_send_to_peer, 620c87c5fbaSopenharmony_ci .read = dtls_application_data, 621c87c5fbaSopenharmony_ci .event = dtls_event, 622c87c5fbaSopenharmony_ci#ifdef DTLS_PSK 623c87c5fbaSopenharmony_ci .get_psk_info = NULL, 624c87c5fbaSopenharmony_ci#endif /* DTLS_PSK */ 625c87c5fbaSopenharmony_ci .get_ecdsa_key = get_ecdsa_key, 626c87c5fbaSopenharmony_ci .verify_ecdsa_key = verify_ecdsa_key 627c87c5fbaSopenharmony_ci}; 628c87c5fbaSopenharmony_ci#endif /* DTLS_ECC */ 629c87c5fbaSopenharmony_ci 630c87c5fbaSopenharmony_cistatic dtls_handler_t psk_cb = { 631c87c5fbaSopenharmony_ci .write = dtls_send_to_peer, 632c87c5fbaSopenharmony_ci .read = dtls_application_data, 633c87c5fbaSopenharmony_ci .event = dtls_event, 634c87c5fbaSopenharmony_ci#ifdef DTLS_PSK 635c87c5fbaSopenharmony_ci .get_psk_info = get_psk_info, 636c87c5fbaSopenharmony_ci#endif /* DTLS_PSK */ 637c87c5fbaSopenharmony_ci#ifdef DTLS_ECC 638c87c5fbaSopenharmony_ci .get_ecdsa_key = NULL, 639c87c5fbaSopenharmony_ci .verify_ecdsa_key = NULL 640c87c5fbaSopenharmony_ci#endif /* DTLS_ECC */ 641c87c5fbaSopenharmony_ci}; 642c87c5fbaSopenharmony_ci 643c87c5fbaSopenharmony_civoid * 644c87c5fbaSopenharmony_cicoap_dtls_new_context(coap_context_t *coap_context) { 645c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = coap_malloc_type(COAP_DTLS_CONTEXT, sizeof(coap_tiny_context_t)); 646c87c5fbaSopenharmony_ci struct dtls_context_t *dtls_context = t_context ? dtls_new_context(t_context) : NULL; 647c87c5fbaSopenharmony_ci if (!dtls_context) 648c87c5fbaSopenharmony_ci goto error; 649c87c5fbaSopenharmony_ci memset(t_context, 0, sizeof(coap_tiny_context_t)); 650c87c5fbaSopenharmony_ci t_context->coap_context = coap_context; 651c87c5fbaSopenharmony_ci t_context->dtls_context = dtls_context; 652c87c5fbaSopenharmony_ci dtls_set_handler(dtls_context, &psk_cb); 653c87c5fbaSopenharmony_ci return t_context; 654c87c5fbaSopenharmony_cierror: 655c87c5fbaSopenharmony_ci if (t_context) 656c87c5fbaSopenharmony_ci coap_free_type(COAP_DTLS_CONTEXT, t_context); 657c87c5fbaSopenharmony_ci if (dtls_context) 658c87c5fbaSopenharmony_ci coap_dtls_free_context(dtls_context); 659c87c5fbaSopenharmony_ci return NULL; 660c87c5fbaSopenharmony_ci} 661c87c5fbaSopenharmony_ci 662c87c5fbaSopenharmony_civoid 663c87c5fbaSopenharmony_cicoap_dtls_free_context(void *handle) { 664c87c5fbaSopenharmony_ci if (handle) { 665c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = (coap_tiny_context_t *)handle; 666c87c5fbaSopenharmony_ci#ifdef DTLS_ECC 667c87c5fbaSopenharmony_ci if (t_context->priv_key) { 668c87c5fbaSopenharmony_ci coap_delete_binary(t_context->priv_key); 669c87c5fbaSopenharmony_ci t_context->priv_key = NULL; 670c87c5fbaSopenharmony_ci } 671c87c5fbaSopenharmony_ci if (t_context->pub_key) { 672c87c5fbaSopenharmony_ci coap_delete_binary(t_context->pub_key); 673c87c5fbaSopenharmony_ci t_context->pub_key = NULL; 674c87c5fbaSopenharmony_ci } 675c87c5fbaSopenharmony_ci#endif /* DTLS_ECC */ 676c87c5fbaSopenharmony_ci if (t_context->dtls_context) 677c87c5fbaSopenharmony_ci dtls_free_context(t_context->dtls_context); 678c87c5fbaSopenharmony_ci coap_free_type(COAP_DTLS_CONTEXT, t_context); 679c87c5fbaSopenharmony_ci } 680c87c5fbaSopenharmony_ci} 681c87c5fbaSopenharmony_ci 682c87c5fbaSopenharmony_cistatic session_t * 683c87c5fbaSopenharmony_cicoap_dtls_new_session(coap_session_t *session) { 684c87c5fbaSopenharmony_ci session_t *dtls_session = coap_malloc_type(COAP_DTLS_SESSION, sizeof(session_t)); 685c87c5fbaSopenharmony_ci 686c87c5fbaSopenharmony_ci if (dtls_session) { 687c87c5fbaSopenharmony_ci /* create tinydtls session object from remote address and local 688c87c5fbaSopenharmony_ci * endpoint handle */ 689c87c5fbaSopenharmony_ci dtls_session_init(dtls_session); 690c87c5fbaSopenharmony_ci put_session_addr(&session->addr_info.remote, dtls_session); 691c87c5fbaSopenharmony_ci dtls_session->ifindex = session->ifindex; 692c87c5fbaSopenharmony_ci coap_log_debug("***new session %p\n", (void *)dtls_session); 693c87c5fbaSopenharmony_ci } 694c87c5fbaSopenharmony_ci 695c87c5fbaSopenharmony_ci return dtls_session; 696c87c5fbaSopenharmony_ci} 697c87c5fbaSopenharmony_ci 698c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 699c87c5fbaSopenharmony_civoid * 700c87c5fbaSopenharmony_cicoap_dtls_new_server_session(coap_session_t *session) { 701c87c5fbaSopenharmony_ci return coap_dtls_new_session(session); 702c87c5fbaSopenharmony_ci} 703c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 704c87c5fbaSopenharmony_ci 705c87c5fbaSopenharmony_ci#if COAP_CLIENT_SUPPORT 706c87c5fbaSopenharmony_civoid * 707c87c5fbaSopenharmony_cicoap_dtls_new_client_session(coap_session_t *session) { 708c87c5fbaSopenharmony_ci dtls_peer_t *peer; 709c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = (coap_tiny_context_t *)session->context->dtls_context; 710c87c5fbaSopenharmony_ci dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL; 711c87c5fbaSopenharmony_ci session_t *dtls_session = dtls_context ? coap_dtls_new_session(session) : NULL; 712c87c5fbaSopenharmony_ci 713c87c5fbaSopenharmony_ci if (!dtls_session) 714c87c5fbaSopenharmony_ci return NULL; 715c87c5fbaSopenharmony_ci peer = 716c87c5fbaSopenharmony_ci dtls_get_peer(dtls_context, dtls_session); 717c87c5fbaSopenharmony_ci 718c87c5fbaSopenharmony_ci if (!peer) { 719c87c5fbaSopenharmony_ci /* The peer connection does not yet exist. */ 720c87c5fbaSopenharmony_ci /* dtls_connect() returns a value greater than zero if a new 721c87c5fbaSopenharmony_ci * connection attempt is made, 0 for session reuse. */ 722c87c5fbaSopenharmony_ci if (dtls_connect(dtls_context, dtls_session) >= 0) { 723c87c5fbaSopenharmony_ci peer = 724c87c5fbaSopenharmony_ci dtls_get_peer(dtls_context, dtls_session); 725c87c5fbaSopenharmony_ci } 726c87c5fbaSopenharmony_ci } 727c87c5fbaSopenharmony_ci 728c87c5fbaSopenharmony_ci if (!peer) { 729c87c5fbaSopenharmony_ci /* delete existing session because the peer object has been invalidated */ 730c87c5fbaSopenharmony_ci coap_free_type(COAP_DTLS_SESSION, dtls_session); 731c87c5fbaSopenharmony_ci dtls_session = NULL; 732c87c5fbaSopenharmony_ci } 733c87c5fbaSopenharmony_ci 734c87c5fbaSopenharmony_ci return dtls_session; 735c87c5fbaSopenharmony_ci} 736c87c5fbaSopenharmony_ci#endif /* COAP_CLIENT_SUPPORT */ 737c87c5fbaSopenharmony_ci 738c87c5fbaSopenharmony_civoid 739c87c5fbaSopenharmony_cicoap_dtls_session_update_mtu(coap_session_t *session) { 740c87c5fbaSopenharmony_ci (void)session; 741c87c5fbaSopenharmony_ci} 742c87c5fbaSopenharmony_ci 743c87c5fbaSopenharmony_civoid 744c87c5fbaSopenharmony_cicoap_dtls_free_session(coap_session_t *coap_session) { 745c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = 746c87c5fbaSopenharmony_ci (coap_tiny_context_t *)coap_session->context->dtls_context; 747c87c5fbaSopenharmony_ci dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL; 748c87c5fbaSopenharmony_ci 749c87c5fbaSopenharmony_ci if (dtls_context == NULL) 750c87c5fbaSopenharmony_ci return; 751c87c5fbaSopenharmony_ci if (coap_session->tls && dtls_context) { 752c87c5fbaSopenharmony_ci dtls_peer_t *peer = dtls_get_peer(dtls_context, (session_t *)coap_session->tls); 753c87c5fbaSopenharmony_ci if (peer) 754c87c5fbaSopenharmony_ci dtls_reset_peer(dtls_context, peer); 755c87c5fbaSopenharmony_ci else 756c87c5fbaSopenharmony_ci dtls_close(dtls_context, (session_t *)coap_session->tls); 757c87c5fbaSopenharmony_ci coap_log_debug("***removed session %p\n", coap_session->tls); 758c87c5fbaSopenharmony_ci coap_free_type(COAP_DTLS_SESSION, coap_session->tls); 759c87c5fbaSopenharmony_ci coap_session->tls = NULL; 760c87c5fbaSopenharmony_ci coap_handle_event(coap_session->context, COAP_EVENT_DTLS_CLOSED, coap_session); 761c87c5fbaSopenharmony_ci } 762c87c5fbaSopenharmony_ci} 763c87c5fbaSopenharmony_ci 764c87c5fbaSopenharmony_cissize_t 765c87c5fbaSopenharmony_cicoap_dtls_send(coap_session_t *session, 766c87c5fbaSopenharmony_ci const uint8_t *data, 767c87c5fbaSopenharmony_ci size_t data_len) { 768c87c5fbaSopenharmony_ci int res; 769c87c5fbaSopenharmony_ci uint8_t *data_rw; 770c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = (coap_tiny_context_t *)session->context->dtls_context; 771c87c5fbaSopenharmony_ci dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL; 772c87c5fbaSopenharmony_ci 773c87c5fbaSopenharmony_ci assert(dtls_context); 774c87c5fbaSopenharmony_ci 775c87c5fbaSopenharmony_ci coap_event_dtls = -1; 776c87c5fbaSopenharmony_ci /* Need to do this to not get a compiler warning about const parameters */ 777c87c5fbaSopenharmony_ci memcpy(&data_rw, &data, sizeof(data_rw)); 778c87c5fbaSopenharmony_ci res = dtls_write(dtls_context, 779c87c5fbaSopenharmony_ci (session_t *)session->tls, data_rw, data_len); 780c87c5fbaSopenharmony_ci 781c87c5fbaSopenharmony_ci if (res < 0) 782c87c5fbaSopenharmony_ci coap_log_warn("coap_dtls_send: cannot send PDU\n"); 783c87c5fbaSopenharmony_ci 784c87c5fbaSopenharmony_ci if (coap_event_dtls >= 0) { 785c87c5fbaSopenharmony_ci /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */ 786c87c5fbaSopenharmony_ci if (coap_event_dtls != COAP_EVENT_DTLS_CLOSED) 787c87c5fbaSopenharmony_ci coap_handle_event(session->context, coap_event_dtls, session); 788c87c5fbaSopenharmony_ci if (coap_event_dtls == COAP_EVENT_DTLS_CONNECTED) 789c87c5fbaSopenharmony_ci coap_session_connected(session); 790c87c5fbaSopenharmony_ci else if (coap_event_dtls == COAP_EVENT_DTLS_CLOSED || coap_event_dtls == COAP_EVENT_DTLS_ERROR) 791c87c5fbaSopenharmony_ci coap_session_disconnected(session, COAP_NACK_TLS_FAILED); 792c87c5fbaSopenharmony_ci } 793c87c5fbaSopenharmony_ci 794c87c5fbaSopenharmony_ci if (res > 0) { 795c87c5fbaSopenharmony_ci if (res == (ssize_t)data_len) 796c87c5fbaSopenharmony_ci coap_log_debug("* %s: dtls: sent %4d bytes\n", 797c87c5fbaSopenharmony_ci coap_session_str(session), res); 798c87c5fbaSopenharmony_ci else 799c87c5fbaSopenharmony_ci coap_log_debug("* %s: dtls: sent %4d of %4zd bytes\n", 800c87c5fbaSopenharmony_ci coap_session_str(session), res, data_len); 801c87c5fbaSopenharmony_ci } 802c87c5fbaSopenharmony_ci return res; 803c87c5fbaSopenharmony_ci} 804c87c5fbaSopenharmony_ci 805c87c5fbaSopenharmony_ciint 806c87c5fbaSopenharmony_cicoap_dtls_is_context_timeout(void) { 807c87c5fbaSopenharmony_ci return 1; 808c87c5fbaSopenharmony_ci} 809c87c5fbaSopenharmony_ci 810c87c5fbaSopenharmony_cicoap_tick_t 811c87c5fbaSopenharmony_cicoap_dtls_get_context_timeout(void *tiny_context) { 812c87c5fbaSopenharmony_ci clock_time_t next = 0; 813c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = (coap_tiny_context_t *)tiny_context; 814c87c5fbaSopenharmony_ci dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL; 815c87c5fbaSopenharmony_ci if (tiny_context) 816c87c5fbaSopenharmony_ci dtls_check_retransmit(dtls_context, &next); 817c87c5fbaSopenharmony_ci if (next > 0) 818c87c5fbaSopenharmony_ci return ((coap_tick_t)(next - dtls_tick_0)) * COAP_TICKS_PER_SECOND / DTLS_TICKS_PER_SECOND + 819c87c5fbaSopenharmony_ci coap_tick_0; 820c87c5fbaSopenharmony_ci return 0; 821c87c5fbaSopenharmony_ci} 822c87c5fbaSopenharmony_ci 823c87c5fbaSopenharmony_cicoap_tick_t 824c87c5fbaSopenharmony_cicoap_dtls_get_timeout(coap_session_t *session, coap_tick_t now) { 825c87c5fbaSopenharmony_ci (void)session; 826c87c5fbaSopenharmony_ci (void)now; 827c87c5fbaSopenharmony_ci return 0; 828c87c5fbaSopenharmony_ci} 829c87c5fbaSopenharmony_ci 830c87c5fbaSopenharmony_ci/* 831c87c5fbaSopenharmony_ci * return 1 timed out 832c87c5fbaSopenharmony_ci * 0 still timing out 833c87c5fbaSopenharmony_ci */ 834c87c5fbaSopenharmony_ciint 835c87c5fbaSopenharmony_cicoap_dtls_handle_timeout(coap_session_t *session) { 836c87c5fbaSopenharmony_ci (void)session; 837c87c5fbaSopenharmony_ci return 0; 838c87c5fbaSopenharmony_ci} 839c87c5fbaSopenharmony_ci 840c87c5fbaSopenharmony_ciint 841c87c5fbaSopenharmony_cicoap_dtls_receive(coap_session_t *session, 842c87c5fbaSopenharmony_ci const uint8_t *data, 843c87c5fbaSopenharmony_ci size_t data_len 844c87c5fbaSopenharmony_ci ) { 845c87c5fbaSopenharmony_ci session_t *dtls_session = (session_t *)session->tls; 846c87c5fbaSopenharmony_ci int err; 847c87c5fbaSopenharmony_ci uint8_t *data_rw; 848c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = (coap_tiny_context_t *)session->context->dtls_context; 849c87c5fbaSopenharmony_ci dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL; 850c87c5fbaSopenharmony_ci 851c87c5fbaSopenharmony_ci assert(dtls_context); 852c87c5fbaSopenharmony_ci coap_event_dtls = -1; 853c87c5fbaSopenharmony_ci /* Need to do this to not get a compiler warning about const parameters */ 854c87c5fbaSopenharmony_ci memcpy(&data_rw, &data, sizeof(data_rw)); 855c87c5fbaSopenharmony_ci err = dtls_handle_message(dtls_context, dtls_session, data_rw, (int)data_len); 856c87c5fbaSopenharmony_ci 857c87c5fbaSopenharmony_ci if (err) { 858c87c5fbaSopenharmony_ci coap_event_dtls = COAP_EVENT_DTLS_ERROR; 859c87c5fbaSopenharmony_ci } 860c87c5fbaSopenharmony_ci 861c87c5fbaSopenharmony_ci if (coap_event_dtls >= 0) { 862c87c5fbaSopenharmony_ci /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */ 863c87c5fbaSopenharmony_ci if (coap_event_dtls != COAP_EVENT_DTLS_CLOSED) 864c87c5fbaSopenharmony_ci coap_handle_event(session->context, coap_event_dtls, session); 865c87c5fbaSopenharmony_ci if (coap_event_dtls == COAP_EVENT_DTLS_CONNECTED) 866c87c5fbaSopenharmony_ci coap_session_connected(session); 867c87c5fbaSopenharmony_ci else if (coap_event_dtls == COAP_EVENT_DTLS_CLOSED || coap_event_dtls == COAP_EVENT_DTLS_ERROR) 868c87c5fbaSopenharmony_ci coap_session_disconnected(session, COAP_NACK_TLS_FAILED); 869c87c5fbaSopenharmony_ci } 870c87c5fbaSopenharmony_ci 871c87c5fbaSopenharmony_ci return err; 872c87c5fbaSopenharmony_ci} 873c87c5fbaSopenharmony_ci 874c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 875c87c5fbaSopenharmony_ciint 876c87c5fbaSopenharmony_cicoap_dtls_hello(coap_session_t *session, 877c87c5fbaSopenharmony_ci const uint8_t *data, 878c87c5fbaSopenharmony_ci size_t data_len 879c87c5fbaSopenharmony_ci ) { 880c87c5fbaSopenharmony_ci session_t dtls_session; 881c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context = (coap_tiny_context_t *)session->context->dtls_context; 882c87c5fbaSopenharmony_ci dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL; 883c87c5fbaSopenharmony_ci uint8_t *data_rw; 884c87c5fbaSopenharmony_ci 885c87c5fbaSopenharmony_ci assert(dtls_context); 886c87c5fbaSopenharmony_ci dtls_session_init(&dtls_session); 887c87c5fbaSopenharmony_ci put_session_addr(&session->addr_info.remote, &dtls_session); 888c87c5fbaSopenharmony_ci dtls_session.ifindex = session->ifindex; 889c87c5fbaSopenharmony_ci /* Need to do this to not get a compiler warning about const parameters */ 890c87c5fbaSopenharmony_ci memcpy(&data_rw, &data, sizeof(data_rw)); 891c87c5fbaSopenharmony_ci int res = dtls_handle_message(dtls_context, &dtls_session, 892c87c5fbaSopenharmony_ci data_rw, (int)data_len); 893c87c5fbaSopenharmony_ci if (res >= 0) { 894c87c5fbaSopenharmony_ci if (dtls_get_peer(dtls_context, &dtls_session)) 895c87c5fbaSopenharmony_ci res = 1; 896c87c5fbaSopenharmony_ci else 897c87c5fbaSopenharmony_ci res = 0; 898c87c5fbaSopenharmony_ci } 899c87c5fbaSopenharmony_ci return res; 900c87c5fbaSopenharmony_ci} 901c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 902c87c5fbaSopenharmony_ci 903c87c5fbaSopenharmony_ciunsigned int 904c87c5fbaSopenharmony_cicoap_dtls_get_overhead(coap_session_t *session) { 905c87c5fbaSopenharmony_ci (void)session; 906c87c5fbaSopenharmony_ci return 13 + 8 + 8; 907c87c5fbaSopenharmony_ci} 908c87c5fbaSopenharmony_ci 909c87c5fbaSopenharmony_ciint 910c87c5fbaSopenharmony_cicoap_tls_is_supported(void) { 911c87c5fbaSopenharmony_ci return 0; 912c87c5fbaSopenharmony_ci} 913c87c5fbaSopenharmony_ci 914c87c5fbaSopenharmony_cicoap_tls_version_t * 915c87c5fbaSopenharmony_cicoap_get_tls_library_version(void) { 916c87c5fbaSopenharmony_ci static coap_tls_version_t version; 917c87c5fbaSopenharmony_ci const char *vers = dtls_package_version(); 918c87c5fbaSopenharmony_ci 919c87c5fbaSopenharmony_ci version.version = 0; 920c87c5fbaSopenharmony_ci if (vers) { 921c87c5fbaSopenharmony_ci long int p1, p2 = 0, p3 = 0; 922c87c5fbaSopenharmony_ci char *endptr; 923c87c5fbaSopenharmony_ci 924c87c5fbaSopenharmony_ci p1 = strtol(vers, &endptr, 10); 925c87c5fbaSopenharmony_ci if (*endptr == '.') { 926c87c5fbaSopenharmony_ci p2 = strtol(endptr+1, &endptr, 10); 927c87c5fbaSopenharmony_ci if (*endptr == '.') { 928c87c5fbaSopenharmony_ci p3 = strtol(endptr+1, &endptr, 10); 929c87c5fbaSopenharmony_ci } 930c87c5fbaSopenharmony_ci } 931c87c5fbaSopenharmony_ci version.version = (p1 << 16) | (p2 << 8) | p3; 932c87c5fbaSopenharmony_ci } 933c87c5fbaSopenharmony_ci version.built_version = version.version; 934c87c5fbaSopenharmony_ci version.type = COAP_TLS_LIBRARY_TINYDTLS; 935c87c5fbaSopenharmony_ci return &version; 936c87c5fbaSopenharmony_ci} 937c87c5fbaSopenharmony_ci 938c87c5fbaSopenharmony_ci#ifdef DTLS_ECC 939c87c5fbaSopenharmony_cistatic const uint8_t b64_6[256] = { 940c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 941c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 942c87c5fbaSopenharmony_ci /* + / */ 943c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 944c87c5fbaSopenharmony_ci /* 0 1 2 3 4 5 6 7 8 9 = */ 945c87c5fbaSopenharmony_ci 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 946c87c5fbaSopenharmony_ci /* A B C D E F G H I J K L M N O */ 947c87c5fbaSopenharmony_ci 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 948c87c5fbaSopenharmony_ci /* P Q R S T U V W X Y Z */ 949c87c5fbaSopenharmony_ci 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 950c87c5fbaSopenharmony_ci /* a b c d e f g h i j k l m n o */ 951c87c5fbaSopenharmony_ci 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 952c87c5fbaSopenharmony_ci /* p q r s t u v w x y z */ 953c87c5fbaSopenharmony_ci 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 954c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 955c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 956c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 957c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 958c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 959c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 960c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 961c87c5fbaSopenharmony_ci 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 962c87c5fbaSopenharmony_ci}; 963c87c5fbaSopenharmony_ci 964c87c5fbaSopenharmony_ci/* caller must free off returned coap_binary_t* */ 965c87c5fbaSopenharmony_cistatic coap_binary_t * 966c87c5fbaSopenharmony_cipem_base64_decode(const uint8_t *data, size_t size) { 967c87c5fbaSopenharmony_ci uint8_t *tbuf = coap_malloc_type(COAP_STRING, size); 968c87c5fbaSopenharmony_ci size_t nbytesdecoded; 969c87c5fbaSopenharmony_ci size_t i; 970c87c5fbaSopenharmony_ci coap_binary_t *decoded; 971c87c5fbaSopenharmony_ci uint8_t *ptr; 972c87c5fbaSopenharmony_ci uint8_t *out; 973c87c5fbaSopenharmony_ci size_t nb64bytes = 0; 974c87c5fbaSopenharmony_ci 975c87c5fbaSopenharmony_ci for (i = 0; i < size; i++) { 976c87c5fbaSopenharmony_ci switch (data[i]) { 977c87c5fbaSopenharmony_ci case ' ': 978c87c5fbaSopenharmony_ci case '\r': 979c87c5fbaSopenharmony_ci case '\n': 980c87c5fbaSopenharmony_ci case '\t': 981c87c5fbaSopenharmony_ci break; 982c87c5fbaSopenharmony_ci default: 983c87c5fbaSopenharmony_ci if (b64_6[data[i]] == 64) 984c87c5fbaSopenharmony_ci goto end; 985c87c5fbaSopenharmony_ci tbuf[nb64bytes++] = data[i]; 986c87c5fbaSopenharmony_ci break; 987c87c5fbaSopenharmony_ci } 988c87c5fbaSopenharmony_ci } 989c87c5fbaSopenharmony_ci 990c87c5fbaSopenharmony_ciend: 991c87c5fbaSopenharmony_ci nbytesdecoded = ((nb64bytes + 3) / 4) * 3; 992c87c5fbaSopenharmony_ci decoded = coap_new_binary(nbytesdecoded + 1); 993c87c5fbaSopenharmony_ci if (!decoded) 994c87c5fbaSopenharmony_ci return NULL; 995c87c5fbaSopenharmony_ci 996c87c5fbaSopenharmony_ci out = decoded->s; 997c87c5fbaSopenharmony_ci ptr = tbuf; 998c87c5fbaSopenharmony_ci 999c87c5fbaSopenharmony_ci while (nb64bytes > 4) { 1000c87c5fbaSopenharmony_ci *(out++) = b64_6[ptr[0]] << 2 | b64_6[ptr[1]] >> 4; 1001c87c5fbaSopenharmony_ci *(out++) = b64_6[ptr[1]] << 4 | b64_6[ptr[2]] >> 2; 1002c87c5fbaSopenharmony_ci *(out++) = b64_6[ptr[2]] << 6 | b64_6[ptr[3]]; 1003c87c5fbaSopenharmony_ci ptr += 4; 1004c87c5fbaSopenharmony_ci nb64bytes -= 4; 1005c87c5fbaSopenharmony_ci } 1006c87c5fbaSopenharmony_ci 1007c87c5fbaSopenharmony_ci /* Note: (nb64bytes == 1) is an error */ 1008c87c5fbaSopenharmony_ci if (nb64bytes > 1) { 1009c87c5fbaSopenharmony_ci *(out++) = b64_6[ptr[0]] << 2 | b64_6[ptr[1]] >> 4; 1010c87c5fbaSopenharmony_ci } 1011c87c5fbaSopenharmony_ci if (nb64bytes > 2) { 1012c87c5fbaSopenharmony_ci *(out++) = b64_6[ptr[1]] << 4 | b64_6[ptr[2]] >> 2; 1013c87c5fbaSopenharmony_ci } 1014c87c5fbaSopenharmony_ci if (nb64bytes > 3) { 1015c87c5fbaSopenharmony_ci *(out++) = b64_6[ptr[2]] << 6 | b64_6[ptr[3]]; 1016c87c5fbaSopenharmony_ci } 1017c87c5fbaSopenharmony_ci 1018c87c5fbaSopenharmony_ci decoded->length = nbytesdecoded - ((4 - nb64bytes) & 3); 1019c87c5fbaSopenharmony_ci coap_free_type(COAP_STRING, tbuf); 1020c87c5fbaSopenharmony_ci return decoded; 1021c87c5fbaSopenharmony_ci} 1022c87c5fbaSopenharmony_ci 1023c87c5fbaSopenharmony_citypedef coap_binary_t *(*asn1_callback)(const uint8_t *data, size_t size); 1024c87c5fbaSopenharmony_ci 1025c87c5fbaSopenharmony_cistatic int 1026c87c5fbaSopenharmony_ciasn1_verify_privkey(const uint8_t *data, size_t size) { 1027c87c5fbaSopenharmony_ci /* Check if we have the private key (with optional leading 0x00) */ 1028c87c5fbaSopenharmony_ci /* skip leading 0x00 */ 1029c87c5fbaSopenharmony_ci if (size - 1 == DTLS_EC_KEY_SIZE && *data == '\000') { 1030c87c5fbaSopenharmony_ci --size; 1031c87c5fbaSopenharmony_ci ++data; 1032c87c5fbaSopenharmony_ci } 1033c87c5fbaSopenharmony_ci 1034c87c5fbaSopenharmony_ci /* Check if we have the private key */ 1035c87c5fbaSopenharmony_ci if (size != DTLS_EC_KEY_SIZE) 1036c87c5fbaSopenharmony_ci return 0; 1037c87c5fbaSopenharmony_ci 1038c87c5fbaSopenharmony_ci return 1; 1039c87c5fbaSopenharmony_ci} 1040c87c5fbaSopenharmony_ci 1041c87c5fbaSopenharmony_cistatic int 1042c87c5fbaSopenharmony_ciasn1_verify_pubkey(const uint8_t *data, size_t size) { 1043c87c5fbaSopenharmony_ci (void)data; 1044c87c5fbaSopenharmony_ci 1045c87c5fbaSopenharmony_ci /* We have the public key 1046c87c5fbaSopenharmony_ci (with a leading 0x00 (no unused bits) 0x04 (not compressed() */ 1047c87c5fbaSopenharmony_ci if (size - 2 != 2 * DTLS_EC_KEY_SIZE) 1048c87c5fbaSopenharmony_ci return 0; 1049c87c5fbaSopenharmony_ci 1050c87c5fbaSopenharmony_ci return 1; 1051c87c5fbaSopenharmony_ci} 1052c87c5fbaSopenharmony_ci 1053c87c5fbaSopenharmony_cistatic int 1054c87c5fbaSopenharmony_ciasn1_verify_curve(const uint8_t *data, size_t size) { 1055c87c5fbaSopenharmony_ci static uint8_t prime256v1_oid[] = 1056c87c5fbaSopenharmony_ci /* OID 1.2.840.10045.3.1.7 */ 1057c87c5fbaSopenharmony_ci { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 }; 1058c87c5fbaSopenharmony_ci 1059c87c5fbaSopenharmony_ci /* Check that we have the correct EC (only one supported) */ 1060c87c5fbaSopenharmony_ci if (size != sizeof(prime256v1_oid) || 1061c87c5fbaSopenharmony_ci memcmp(data, prime256v1_oid, size) != 0) 1062c87c5fbaSopenharmony_ci return 0; 1063c87c5fbaSopenharmony_ci 1064c87c5fbaSopenharmony_ci return 1; 1065c87c5fbaSopenharmony_ci} 1066c87c5fbaSopenharmony_ci 1067c87c5fbaSopenharmony_cistatic int 1068c87c5fbaSopenharmony_ciasn1_verify_pkcs8_version(const uint8_t *data, size_t size) { 1069c87c5fbaSopenharmony_ci /* Check that we have the version */ 1070c87c5fbaSopenharmony_ci if (size != 1 || *data != 0) 1071c87c5fbaSopenharmony_ci return 0; 1072c87c5fbaSopenharmony_ci 1073c87c5fbaSopenharmony_ci return 1; 1074c87c5fbaSopenharmony_ci} 1075c87c5fbaSopenharmony_ci 1076c87c5fbaSopenharmony_cistatic int 1077c87c5fbaSopenharmony_ciasn1_verify_ec_identifier(const uint8_t *data, size_t size) { 1078c87c5fbaSopenharmony_ci static uint8_t ec_public_key_oid[] = 1079c87c5fbaSopenharmony_ci /* OID 1.2.840.10045.2.1 */ 1080c87c5fbaSopenharmony_ci { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 }; 1081c87c5fbaSopenharmony_ci 1082c87c5fbaSopenharmony_ci /* Check that we have the correct ecPublicKey */ 1083c87c5fbaSopenharmony_ci if (size != sizeof(ec_public_key_oid) || 1084c87c5fbaSopenharmony_ci memcmp(data, ec_public_key_oid, size) != 0) 1085c87c5fbaSopenharmony_ci return 0; 1086c87c5fbaSopenharmony_ci 1087c87c5fbaSopenharmony_ci return 1; 1088c87c5fbaSopenharmony_ci} 1089c87c5fbaSopenharmony_ci 1090c87c5fbaSopenharmony_cistatic int 1091c87c5fbaSopenharmony_ciasn1_verify_ec_key(const uint8_t *data, size_t size) { 1092c87c5fbaSopenharmony_ci (void)data; 1093c87c5fbaSopenharmony_ci 1094c87c5fbaSopenharmony_ci if (size == 0) 1095c87c5fbaSopenharmony_ci return 0; 1096c87c5fbaSopenharmony_ci 1097c87c5fbaSopenharmony_ci return 1; 1098c87c5fbaSopenharmony_ci} 1099c87c5fbaSopenharmony_ci 1100c87c5fbaSopenharmony_cistatic int 1101c87c5fbaSopenharmony_ciasn1_derive_keys(coap_tiny_context_t *t_context, 1102c87c5fbaSopenharmony_ci const uint8_t *priv_data, size_t priv_len, 1103c87c5fbaSopenharmony_ci const uint8_t *pub_data, size_t pub_len, 1104c87c5fbaSopenharmony_ci int is_pkcs8) { 1105c87c5fbaSopenharmony_ci coap_binary_t *test; 1106c87c5fbaSopenharmony_ci 1107c87c5fbaSopenharmony_ci t_context->priv_key = get_asn1_tag(COAP_ASN1_OCTETSTRING, priv_data, 1108c87c5fbaSopenharmony_ci priv_len, asn1_verify_privkey); 1109c87c5fbaSopenharmony_ci if (!t_context->priv_key) { 1110c87c5fbaSopenharmony_ci coap_log_info("EC Private Key (RPK) invalid\n"); 1111c87c5fbaSopenharmony_ci return 0; 1112c87c5fbaSopenharmony_ci } 1113c87c5fbaSopenharmony_ci /* skip leading 0x00 */ 1114c87c5fbaSopenharmony_ci if (t_context->priv_key->length - 1 == DTLS_EC_KEY_SIZE && 1115c87c5fbaSopenharmony_ci t_context->priv_key->s[0] == '\000') { 1116c87c5fbaSopenharmony_ci t_context->priv_key->length--; 1117c87c5fbaSopenharmony_ci t_context->priv_key->s++; 1118c87c5fbaSopenharmony_ci } 1119c87c5fbaSopenharmony_ci 1120c87c5fbaSopenharmony_ci if (!is_pkcs8) { 1121c87c5fbaSopenharmony_ci /* pkcs8 abstraction tested for valid eliptic curve */ 1122c87c5fbaSopenharmony_ci test = get_asn1_tag(COAP_ASN1_IDENTIFIER, priv_data, priv_len, 1123c87c5fbaSopenharmony_ci asn1_verify_curve); 1124c87c5fbaSopenharmony_ci if (!test) { 1125c87c5fbaSopenharmony_ci coap_log_info("EC Private Key (RPK) invalid elliptic curve\n"); 1126c87c5fbaSopenharmony_ci coap_delete_binary(t_context->priv_key); 1127c87c5fbaSopenharmony_ci t_context->priv_key = NULL; 1128c87c5fbaSopenharmony_ci return 0; 1129c87c5fbaSopenharmony_ci } 1130c87c5fbaSopenharmony_ci coap_delete_binary(test); 1131c87c5fbaSopenharmony_ci } 1132c87c5fbaSopenharmony_ci 1133c87c5fbaSopenharmony_ci t_context->pub_key = get_asn1_tag(COAP_ASN1_BITSTRING, pub_data, pub_len, 1134c87c5fbaSopenharmony_ci asn1_verify_pubkey); 1135c87c5fbaSopenharmony_ci if (!t_context->pub_key) { 1136c87c5fbaSopenharmony_ci coap_log_info("EC Public Key (RPK) invalid\n"); 1137c87c5fbaSopenharmony_ci coap_delete_binary(t_context->priv_key); 1138c87c5fbaSopenharmony_ci t_context->priv_key = NULL; 1139c87c5fbaSopenharmony_ci return 0; 1140c87c5fbaSopenharmony_ci } 1141c87c5fbaSopenharmony_ci /* Drop leading 0x00 and 0x04 */ 1142c87c5fbaSopenharmony_ci t_context->pub_key->s += 2; 1143c87c5fbaSopenharmony_ci t_context->pub_key->length -= 2; 1144c87c5fbaSopenharmony_ci dtls_set_handler(t_context->dtls_context, &ec_cb); 1145c87c5fbaSopenharmony_ci return 1; 1146c87c5fbaSopenharmony_ci} 1147c87c5fbaSopenharmony_ci 1148c87c5fbaSopenharmony_cistatic coap_binary_t * 1149c87c5fbaSopenharmony_ciec_abstract_pkcs8_asn1(const uint8_t *asn1_ptr, size_t asn1_length) { 1150c87c5fbaSopenharmony_ci coap_binary_t *test; 1151c87c5fbaSopenharmony_ci 1152c87c5fbaSopenharmony_ci test = get_asn1_tag(COAP_ASN1_INTEGER, asn1_ptr, asn1_length, 1153c87c5fbaSopenharmony_ci asn1_verify_pkcs8_version); 1154c87c5fbaSopenharmony_ci if (!test) 1155c87c5fbaSopenharmony_ci return 0; 1156c87c5fbaSopenharmony_ci 1157c87c5fbaSopenharmony_ci coap_delete_binary(test); 1158c87c5fbaSopenharmony_ci 1159c87c5fbaSopenharmony_ci test = get_asn1_tag(COAP_ASN1_IDENTIFIER, asn1_ptr, asn1_length, 1160c87c5fbaSopenharmony_ci asn1_verify_ec_identifier); 1161c87c5fbaSopenharmony_ci if (!test) 1162c87c5fbaSopenharmony_ci return 0; 1163c87c5fbaSopenharmony_ci coap_delete_binary(test); 1164c87c5fbaSopenharmony_ci 1165c87c5fbaSopenharmony_ci test = get_asn1_tag(COAP_ASN1_IDENTIFIER, asn1_ptr, asn1_length, 1166c87c5fbaSopenharmony_ci asn1_verify_curve); 1167c87c5fbaSopenharmony_ci if (!test) { 1168c87c5fbaSopenharmony_ci coap_log_info("EC Private Key (RPK) invalid elliptic curve\n"); 1169c87c5fbaSopenharmony_ci return 0; 1170c87c5fbaSopenharmony_ci } 1171c87c5fbaSopenharmony_ci coap_delete_binary(test); 1172c87c5fbaSopenharmony_ci 1173c87c5fbaSopenharmony_ci test = get_asn1_tag(COAP_ASN1_OCTETSTRING, asn1_ptr, asn1_length, 1174c87c5fbaSopenharmony_ci asn1_verify_ec_key); 1175c87c5fbaSopenharmony_ci return test; 1176c87c5fbaSopenharmony_ci} 1177c87c5fbaSopenharmony_ci 1178c87c5fbaSopenharmony_cistatic coap_binary_t * 1179c87c5fbaSopenharmony_cipem_decode_mem_asn1(const char *begstr, const uint8_t *str) { 1180c87c5fbaSopenharmony_ci char *bcp = str ? strstr((const char *)str, begstr) : NULL; 1181c87c5fbaSopenharmony_ci char *tcp = bcp ? strstr(bcp, "-----END ") : NULL; 1182c87c5fbaSopenharmony_ci 1183c87c5fbaSopenharmony_ci if (bcp && tcp) { 1184c87c5fbaSopenharmony_ci bcp += strlen(begstr); 1185c87c5fbaSopenharmony_ci return pem_base64_decode((const uint8_t *)bcp, tcp - bcp); 1186c87c5fbaSopenharmony_ci } 1187c87c5fbaSopenharmony_ci return NULL; 1188c87c5fbaSopenharmony_ci} 1189c87c5fbaSopenharmony_ci 1190c87c5fbaSopenharmony_ci#endif /* DTLS_ECC */ 1191c87c5fbaSopenharmony_ci 1192c87c5fbaSopenharmony_ciint 1193c87c5fbaSopenharmony_cicoap_dtls_context_set_pki(coap_context_t *ctx, 1194c87c5fbaSopenharmony_ci const coap_dtls_pki_t *setup_data, 1195c87c5fbaSopenharmony_ci const coap_dtls_role_t role COAP_UNUSED) { 1196c87c5fbaSopenharmony_ci#ifdef DTLS_ECC 1197c87c5fbaSopenharmony_ci coap_tiny_context_t *t_context; 1198c87c5fbaSopenharmony_ci coap_binary_t *asn1_priv; 1199c87c5fbaSopenharmony_ci coap_binary_t *asn1_pub; 1200c87c5fbaSopenharmony_ci coap_binary_t *asn1_temp; 1201c87c5fbaSopenharmony_ci int is_pkcs8 = 0; 1202c87c5fbaSopenharmony_ci 1203c87c5fbaSopenharmony_ci if (!setup_data) 1204c87c5fbaSopenharmony_ci return 0; 1205c87c5fbaSopenharmony_ci if (setup_data->version != COAP_DTLS_PKI_SETUP_VERSION) 1206c87c5fbaSopenharmony_ci return 0; 1207c87c5fbaSopenharmony_ci if (!setup_data->is_rpk_not_cert) { 1208c87c5fbaSopenharmony_ci coap_log_warn("Only RPK, not full PKI is supported\n"); 1209c87c5fbaSopenharmony_ci return 0; 1210c87c5fbaSopenharmony_ci } 1211c87c5fbaSopenharmony_ci if (!ctx) 1212c87c5fbaSopenharmony_ci return 0; 1213c87c5fbaSopenharmony_ci t_context = (coap_tiny_context_t *)ctx->dtls_context; 1214c87c5fbaSopenharmony_ci if (!t_context) 1215c87c5fbaSopenharmony_ci return 0; 1216c87c5fbaSopenharmony_ci if (t_context->priv_key) { 1217c87c5fbaSopenharmony_ci coap_delete_binary(t_context->priv_key); 1218c87c5fbaSopenharmony_ci t_context->priv_key = NULL; 1219c87c5fbaSopenharmony_ci } 1220c87c5fbaSopenharmony_ci if (t_context->pub_key) { 1221c87c5fbaSopenharmony_ci coap_delete_binary(t_context->pub_key); 1222c87c5fbaSopenharmony_ci t_context->pub_key = NULL; 1223c87c5fbaSopenharmony_ci } 1224c87c5fbaSopenharmony_ci t_context->setup_data = *setup_data; 1225c87c5fbaSopenharmony_ci 1226c87c5fbaSopenharmony_ci /* All should be RPK only now */ 1227c87c5fbaSopenharmony_ci switch (setup_data->pki_key.key_type) { 1228c87c5fbaSopenharmony_ci case COAP_PKI_KEY_PEM: 1229c87c5fbaSopenharmony_ci coap_log_warn("RPK keys cannot be in COAP_PKI_KEY_PEM format\n"); 1230c87c5fbaSopenharmony_ci break; 1231c87c5fbaSopenharmony_ci case COAP_PKI_KEY_PEM_BUF: 1232c87c5fbaSopenharmony_ci if (setup_data->pki_key.key.pem_buf.public_cert && 1233c87c5fbaSopenharmony_ci setup_data->pki_key.key.pem_buf.public_cert[0] && 1234c87c5fbaSopenharmony_ci setup_data->pki_key.key.pem_buf.private_key && 1235c87c5fbaSopenharmony_ci setup_data->pki_key.key.pem_buf.private_key[0]) { 1236c87c5fbaSopenharmony_ci /* Need to take PEM memory information and convert to binary */ 1237c87c5fbaSopenharmony_ci asn1_priv = pem_decode_mem_asn1("-----BEGIN EC PRIVATE KEY-----", 1238c87c5fbaSopenharmony_ci setup_data->pki_key.key.pem_buf.private_key); 1239c87c5fbaSopenharmony_ci if (!asn1_priv) { 1240c87c5fbaSopenharmony_ci asn1_priv = pem_decode_mem_asn1("-----BEGIN PRIVATE KEY-----", 1241c87c5fbaSopenharmony_ci setup_data->pki_key.key.pem_buf.private_key); 1242c87c5fbaSopenharmony_ci if (!asn1_priv) { 1243c87c5fbaSopenharmony_ci coap_log_info("Private Key (RPK) invalid\n"); 1244c87c5fbaSopenharmony_ci return 0; 1245c87c5fbaSopenharmony_ci } 1246c87c5fbaSopenharmony_ci asn1_temp = ec_abstract_pkcs8_asn1(asn1_priv->s, asn1_priv->length); 1247c87c5fbaSopenharmony_ci if (!asn1_temp) { 1248c87c5fbaSopenharmony_ci coap_log_info("PKCS#8 Private Key (RPK) invalid\n"); 1249c87c5fbaSopenharmony_ci coap_delete_binary(asn1_priv); 1250c87c5fbaSopenharmony_ci return 0; 1251c87c5fbaSopenharmony_ci } 1252c87c5fbaSopenharmony_ci coap_delete_binary(asn1_priv); 1253c87c5fbaSopenharmony_ci asn1_priv = asn1_temp; 1254c87c5fbaSopenharmony_ci is_pkcs8 = 1; 1255c87c5fbaSopenharmony_ci } 1256c87c5fbaSopenharmony_ci asn1_pub = pem_decode_mem_asn1( 1257c87c5fbaSopenharmony_ci "-----BEGIN PUBLIC KEY-----", 1258c87c5fbaSopenharmony_ci setup_data->pki_key.key.pem_buf.public_cert); 1259c87c5fbaSopenharmony_ci if (!asn1_pub) { 1260c87c5fbaSopenharmony_ci asn1_pub = pem_decode_mem_asn1("-----BEGIN EC PRIVATE KEY-----", 1261c87c5fbaSopenharmony_ci setup_data->pki_key.key.pem_buf.private_key); 1262c87c5fbaSopenharmony_ci if (!asn1_pub) { 1263c87c5fbaSopenharmony_ci asn1_pub = pem_decode_mem_asn1("-----BEGIN PRIVATE KEY-----", 1264c87c5fbaSopenharmony_ci setup_data->pki_key.key.pem_buf.private_key); 1265c87c5fbaSopenharmony_ci if (!asn1_pub) { 1266c87c5fbaSopenharmony_ci coap_log_info("Public Key (RPK) invalid\n"); 1267c87c5fbaSopenharmony_ci coap_delete_binary(asn1_priv); 1268c87c5fbaSopenharmony_ci return 0; 1269c87c5fbaSopenharmony_ci } 1270c87c5fbaSopenharmony_ci asn1_temp = ec_abstract_pkcs8_asn1(asn1_pub->s, asn1_pub->length); 1271c87c5fbaSopenharmony_ci if (!asn1_temp) { 1272c87c5fbaSopenharmony_ci coap_log_info("PKCS#8 Private Key (RPK) invalid\n"); 1273c87c5fbaSopenharmony_ci coap_delete_binary(asn1_priv); 1274c87c5fbaSopenharmony_ci coap_delete_binary(asn1_pub); 1275c87c5fbaSopenharmony_ci return 0; 1276c87c5fbaSopenharmony_ci } 1277c87c5fbaSopenharmony_ci coap_delete_binary(asn1_pub); 1278c87c5fbaSopenharmony_ci asn1_pub = asn1_temp; 1279c87c5fbaSopenharmony_ci is_pkcs8 = 1; 1280c87c5fbaSopenharmony_ci } 1281c87c5fbaSopenharmony_ci } 1282c87c5fbaSopenharmony_ci if (!asn1_derive_keys(t_context, asn1_priv->s, asn1_priv->length, 1283c87c5fbaSopenharmony_ci asn1_pub->s, asn1_pub->length, is_pkcs8)) { 1284c87c5fbaSopenharmony_ci coap_log_info("Unable to derive Public/Private Keys\n"); 1285c87c5fbaSopenharmony_ci coap_delete_binary(asn1_priv); 1286c87c5fbaSopenharmony_ci coap_delete_binary(asn1_pub); 1287c87c5fbaSopenharmony_ci return 0; 1288c87c5fbaSopenharmony_ci } 1289c87c5fbaSopenharmony_ci coap_delete_binary(asn1_priv); 1290c87c5fbaSopenharmony_ci coap_delete_binary(asn1_pub); 1291c87c5fbaSopenharmony_ci return 1; 1292c87c5fbaSopenharmony_ci } 1293c87c5fbaSopenharmony_ci break; 1294c87c5fbaSopenharmony_ci case COAP_PKI_KEY_ASN1: 1295c87c5fbaSopenharmony_ci if (setup_data->pki_key.key.asn1.private_key && 1296c87c5fbaSopenharmony_ci setup_data->pki_key.key.asn1.private_key_len && 1297c87c5fbaSopenharmony_ci setup_data->pki_key.key.asn1.private_key_type == COAP_ASN1_PKEY_EC) { 1298c87c5fbaSopenharmony_ci const uint8_t *private_key = setup_data->pki_key.key.asn1.private_key; 1299c87c5fbaSopenharmony_ci size_t private_key_len = setup_data->pki_key.key.asn1.private_key_len; 1300c87c5fbaSopenharmony_ci 1301c87c5fbaSopenharmony_ci /* Check to see whether this is in pkcs8 format or not */ 1302c87c5fbaSopenharmony_ci asn1_temp = ec_abstract_pkcs8_asn1( 1303c87c5fbaSopenharmony_ci setup_data->pki_key.key.asn1.private_key, 1304c87c5fbaSopenharmony_ci setup_data->pki_key.key.asn1.private_key_len); 1305c87c5fbaSopenharmony_ci if (asn1_temp) { 1306c87c5fbaSopenharmony_ci private_key = asn1_temp->s; 1307c87c5fbaSopenharmony_ci private_key_len = asn1_temp->length; 1308c87c5fbaSopenharmony_ci is_pkcs8 = 1; 1309c87c5fbaSopenharmony_ci } 1310c87c5fbaSopenharmony_ci /* Need to take ASN1 memory information and convert to binary */ 1311c87c5fbaSopenharmony_ci if (setup_data->pki_key.key.asn1.public_cert && 1312c87c5fbaSopenharmony_ci setup_data->pki_key.key.asn1.public_cert_len) { 1313c87c5fbaSopenharmony_ci if (!asn1_derive_keys(t_context, 1314c87c5fbaSopenharmony_ci private_key, 1315c87c5fbaSopenharmony_ci private_key_len, 1316c87c5fbaSopenharmony_ci setup_data->pki_key.key.asn1.public_cert, 1317c87c5fbaSopenharmony_ci setup_data->pki_key.key.asn1.public_cert_len, 1318c87c5fbaSopenharmony_ci is_pkcs8)) { 1319c87c5fbaSopenharmony_ci coap_log_info("Unable to derive Public/Private Keys\n"); 1320c87c5fbaSopenharmony_ci if (asn1_temp) 1321c87c5fbaSopenharmony_ci coap_delete_binary(asn1_temp); 1322c87c5fbaSopenharmony_ci return 0; 1323c87c5fbaSopenharmony_ci } 1324c87c5fbaSopenharmony_ci } else { 1325c87c5fbaSopenharmony_ci if (!asn1_derive_keys(t_context, 1326c87c5fbaSopenharmony_ci private_key, 1327c87c5fbaSopenharmony_ci private_key_len, 1328c87c5fbaSopenharmony_ci private_key, 1329c87c5fbaSopenharmony_ci private_key_len, 1330c87c5fbaSopenharmony_ci is_pkcs8)) { 1331c87c5fbaSopenharmony_ci coap_log_info("Unable to derive Public/Private Keys\n"); 1332c87c5fbaSopenharmony_ci if (asn1_temp) 1333c87c5fbaSopenharmony_ci coap_delete_binary(asn1_temp); 1334c87c5fbaSopenharmony_ci return 0; 1335c87c5fbaSopenharmony_ci } 1336c87c5fbaSopenharmony_ci } 1337c87c5fbaSopenharmony_ci return 1; 1338c87c5fbaSopenharmony_ci } 1339c87c5fbaSopenharmony_ci break; 1340c87c5fbaSopenharmony_ci case COAP_PKI_KEY_PKCS11: 1341c87c5fbaSopenharmony_ci coap_log_warn("RPK keys cannot be in COAP_PKI_KEY_PCKS11 format\n"); 1342c87c5fbaSopenharmony_ci break; 1343c87c5fbaSopenharmony_ci default: 1344c87c5fbaSopenharmony_ci break; 1345c87c5fbaSopenharmony_ci } 1346c87c5fbaSopenharmony_ci#else /* ! DTLS_ECC */ 1347c87c5fbaSopenharmony_ci (void)ctx; 1348c87c5fbaSopenharmony_ci (void)setup_data; 1349c87c5fbaSopenharmony_ci#endif /* ! DTLS_ECC */ 1350c87c5fbaSopenharmony_ci coap_log_warn("TinyDTLS not compiled with ECC support\n"); 1351c87c5fbaSopenharmony_ci return 0; 1352c87c5fbaSopenharmony_ci} 1353c87c5fbaSopenharmony_ci 1354c87c5fbaSopenharmony_ciint 1355c87c5fbaSopenharmony_cicoap_dtls_context_set_pki_root_cas(coap_context_t *ctx COAP_UNUSED, 1356c87c5fbaSopenharmony_ci const char *ca_file COAP_UNUSED, 1357c87c5fbaSopenharmony_ci const char *ca_path COAP_UNUSED 1358c87c5fbaSopenharmony_ci ) { 1359c87c5fbaSopenharmony_ci coap_log_warn("Root CAs PKI not supported\n"); 1360c87c5fbaSopenharmony_ci return 0; 1361c87c5fbaSopenharmony_ci} 1362c87c5fbaSopenharmony_ci 1363c87c5fbaSopenharmony_ci#if COAP_CLIENT_SUPPORT 1364c87c5fbaSopenharmony_ciint 1365c87c5fbaSopenharmony_cicoap_dtls_context_set_cpsk(coap_context_t *coap_context COAP_UNUSED, 1366c87c5fbaSopenharmony_ci coap_dtls_cpsk_t *setup_data 1367c87c5fbaSopenharmony_ci ) { 1368c87c5fbaSopenharmony_ci if (!setup_data) 1369c87c5fbaSopenharmony_ci return 0; 1370c87c5fbaSopenharmony_ci 1371c87c5fbaSopenharmony_ci#ifdef DTLS_PSK 1372c87c5fbaSopenharmony_ci return 1; 1373c87c5fbaSopenharmony_ci#else /* ! DTLS_PSK */ 1374c87c5fbaSopenharmony_ci coap_log_warn("TinyDTLS not compiled with PSK support\n"); 1375c87c5fbaSopenharmony_ci return 0; 1376c87c5fbaSopenharmony_ci#endif /* ! DTLS_PSK */ 1377c87c5fbaSopenharmony_ci} 1378c87c5fbaSopenharmony_ci#endif /* COAP_CLIENT_SUPPORT */ 1379c87c5fbaSopenharmony_ci 1380c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 1381c87c5fbaSopenharmony_ciint 1382c87c5fbaSopenharmony_cicoap_dtls_context_set_spsk(coap_context_t *coap_context COAP_UNUSED, 1383c87c5fbaSopenharmony_ci coap_dtls_spsk_t *setup_data 1384c87c5fbaSopenharmony_ci ) { 1385c87c5fbaSopenharmony_ci if (!setup_data) 1386c87c5fbaSopenharmony_ci return 0; 1387c87c5fbaSopenharmony_ci 1388c87c5fbaSopenharmony_ci#ifdef DTLS_PSK 1389c87c5fbaSopenharmony_ci if (setup_data->validate_sni_call_back) { 1390c87c5fbaSopenharmony_ci coap_log_warn("CoAP Server with TinyDTLS does not support SNI selection\n"); 1391c87c5fbaSopenharmony_ci } 1392c87c5fbaSopenharmony_ci 1393c87c5fbaSopenharmony_ci return 1; 1394c87c5fbaSopenharmony_ci#else /* ! DTLS_PSK */ 1395c87c5fbaSopenharmony_ci coap_log_warn("TinyDTLS not compiled with PSK support\n"); 1396c87c5fbaSopenharmony_ci return 0; 1397c87c5fbaSopenharmony_ci#endif /* ! DTLS_PSK */ 1398c87c5fbaSopenharmony_ci} 1399c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 1400c87c5fbaSopenharmony_ci 1401c87c5fbaSopenharmony_ciint 1402c87c5fbaSopenharmony_cicoap_dtls_context_check_keys_enabled(coap_context_t *ctx COAP_UNUSED) { 1403c87c5fbaSopenharmony_ci return 1; 1404c87c5fbaSopenharmony_ci} 1405c87c5fbaSopenharmony_ci 1406c87c5fbaSopenharmony_ci#if !COAP_DISABLE_TCP 1407c87c5fbaSopenharmony_ci#if COAP_CLIENT_SUPPORT 1408c87c5fbaSopenharmony_civoid * 1409c87c5fbaSopenharmony_cicoap_tls_new_client_session(coap_session_t *session COAP_UNUSED) { 1410c87c5fbaSopenharmony_ci return NULL; 1411c87c5fbaSopenharmony_ci} 1412c87c5fbaSopenharmony_ci#endif /* COAP_CLIENT_SUPPORT */ 1413c87c5fbaSopenharmony_ci 1414c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 1415c87c5fbaSopenharmony_civoid * 1416c87c5fbaSopenharmony_cicoap_tls_new_server_session(coap_session_t *session COAP_UNUSED) { 1417c87c5fbaSopenharmony_ci return NULL; 1418c87c5fbaSopenharmony_ci} 1419c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 1420c87c5fbaSopenharmony_ci 1421c87c5fbaSopenharmony_civoid 1422c87c5fbaSopenharmony_cicoap_tls_free_session(coap_session_t *coap_session COAP_UNUSED) { 1423c87c5fbaSopenharmony_ci} 1424c87c5fbaSopenharmony_ci 1425c87c5fbaSopenharmony_ci/* 1426c87c5fbaSopenharmony_ci * strm 1427c87c5fbaSopenharmony_ci * return +ve Number of bytes written. 1428c87c5fbaSopenharmony_ci * -1 Error (error in errno). 1429c87c5fbaSopenharmony_ci */ 1430c87c5fbaSopenharmony_cissize_t 1431c87c5fbaSopenharmony_cicoap_tls_write(coap_session_t *session COAP_UNUSED, 1432c87c5fbaSopenharmony_ci const uint8_t *data COAP_UNUSED, 1433c87c5fbaSopenharmony_ci size_t data_len COAP_UNUSED 1434c87c5fbaSopenharmony_ci ) { 1435c87c5fbaSopenharmony_ci return -1; 1436c87c5fbaSopenharmony_ci} 1437c87c5fbaSopenharmony_ci 1438c87c5fbaSopenharmony_ci/* 1439c87c5fbaSopenharmony_ci * strm 1440c87c5fbaSopenharmony_ci * return >=0 Number of bytes read. 1441c87c5fbaSopenharmony_ci * -1 Error (error in errno). 1442c87c5fbaSopenharmony_ci */ 1443c87c5fbaSopenharmony_cissize_t 1444c87c5fbaSopenharmony_cicoap_tls_read(coap_session_t *session COAP_UNUSED, 1445c87c5fbaSopenharmony_ci uint8_t *data COAP_UNUSED, 1446c87c5fbaSopenharmony_ci size_t data_len COAP_UNUSED) { 1447c87c5fbaSopenharmony_ci errno = ENODEV; 1448c87c5fbaSopenharmony_ci return -1; 1449c87c5fbaSopenharmony_ci} 1450c87c5fbaSopenharmony_ci#endif /* !COAP_DISABLE_TCP */ 1451c87c5fbaSopenharmony_ci 1452c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 1453c87c5fbaSopenharmony_cicoap_digest_ctx_t * 1454c87c5fbaSopenharmony_cicoap_digest_setup(void) { 1455c87c5fbaSopenharmony_ci dtls_sha256_ctx *digest_ctx = coap_malloc_type(COAP_STRING, sizeof(dtls_sha256_ctx)); 1456c87c5fbaSopenharmony_ci 1457c87c5fbaSopenharmony_ci if (digest_ctx) { 1458c87c5fbaSopenharmony_ci dtls_sha256_init(digest_ctx); 1459c87c5fbaSopenharmony_ci } 1460c87c5fbaSopenharmony_ci 1461c87c5fbaSopenharmony_ci return digest_ctx; 1462c87c5fbaSopenharmony_ci} 1463c87c5fbaSopenharmony_ci 1464c87c5fbaSopenharmony_civoid 1465c87c5fbaSopenharmony_cicoap_digest_free(coap_digest_ctx_t *digest_ctx) { 1466c87c5fbaSopenharmony_ci coap_free_type(COAP_STRING, digest_ctx); 1467c87c5fbaSopenharmony_ci} 1468c87c5fbaSopenharmony_ci 1469c87c5fbaSopenharmony_ciint 1470c87c5fbaSopenharmony_cicoap_digest_update(coap_digest_ctx_t *digest_ctx, 1471c87c5fbaSopenharmony_ci const uint8_t *data, 1472c87c5fbaSopenharmony_ci size_t data_len) { 1473c87c5fbaSopenharmony_ci dtls_sha256_update(digest_ctx, data, data_len); 1474c87c5fbaSopenharmony_ci 1475c87c5fbaSopenharmony_ci return 1; 1476c87c5fbaSopenharmony_ci} 1477c87c5fbaSopenharmony_ci 1478c87c5fbaSopenharmony_ciint 1479c87c5fbaSopenharmony_cicoap_digest_final(coap_digest_ctx_t *digest_ctx, 1480c87c5fbaSopenharmony_ci coap_digest_t *digest_buffer) { 1481c87c5fbaSopenharmony_ci dtls_sha256_final((uint8_t *)digest_buffer, digest_ctx); 1482c87c5fbaSopenharmony_ci 1483c87c5fbaSopenharmony_ci coap_digest_free(digest_ctx); 1484c87c5fbaSopenharmony_ci return 1; 1485c87c5fbaSopenharmony_ci} 1486c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 1487c87c5fbaSopenharmony_ci 1488c87c5fbaSopenharmony_ci#if COAP_WS_SUPPORT 1489c87c5fbaSopenharmony_ciint 1490c87c5fbaSopenharmony_cicoap_crypto_hash(cose_alg_t alg, 1491c87c5fbaSopenharmony_ci const coap_bin_const_t *data, 1492c87c5fbaSopenharmony_ci coap_bin_const_t **hash) { 1493c87c5fbaSopenharmony_ci (void)alg; 1494c87c5fbaSopenharmony_ci (void)data; 1495c87c5fbaSopenharmony_ci (void)hash; 1496c87c5fbaSopenharmony_ci return 0; 1497c87c5fbaSopenharmony_ci} 1498c87c5fbaSopenharmony_ci#endif /* COAP_WS_SUPPORT */ 1499c87c5fbaSopenharmony_ci 1500c87c5fbaSopenharmony_ci#if COAP_OSCORE_SUPPORT 1501c87c5fbaSopenharmony_ci 1502c87c5fbaSopenharmony_ciint 1503c87c5fbaSopenharmony_cicoap_oscore_is_supported(void) { 1504c87c5fbaSopenharmony_ci return 1; 1505c87c5fbaSopenharmony_ci} 1506c87c5fbaSopenharmony_ci 1507c87c5fbaSopenharmony_ci/* 1508c87c5fbaSopenharmony_ci * The struct cipher_algs and the function get_cipher_alg() are used to 1509c87c5fbaSopenharmony_ci * determine which cipher type to use for creating the required cipher 1510c87c5fbaSopenharmony_ci * suite object. 1511c87c5fbaSopenharmony_ci */ 1512c87c5fbaSopenharmony_cistatic struct cipher_algs { 1513c87c5fbaSopenharmony_ci cose_alg_t alg; 1514c87c5fbaSopenharmony_ci u_int cipher_type; 1515c87c5fbaSopenharmony_ci} ciphers[] = { 1516c87c5fbaSopenharmony_ci { COSE_ALGORITHM_AES_CCM_16_64_128, 1 }, 1517c87c5fbaSopenharmony_ci}; 1518c87c5fbaSopenharmony_ci 1519c87c5fbaSopenharmony_cistatic u_int 1520c87c5fbaSopenharmony_ciget_cipher_alg(cose_alg_t alg) { 1521c87c5fbaSopenharmony_ci size_t idx; 1522c87c5fbaSopenharmony_ci 1523c87c5fbaSopenharmony_ci for (idx = 0; idx < sizeof(ciphers)/sizeof(struct cipher_algs); idx++) { 1524c87c5fbaSopenharmony_ci if (ciphers[idx].alg == alg) 1525c87c5fbaSopenharmony_ci return ciphers[idx].cipher_type; 1526c87c5fbaSopenharmony_ci } 1527c87c5fbaSopenharmony_ci coap_log_debug("get_cipher_alg: COSE cipher %d not supported\n", alg); 1528c87c5fbaSopenharmony_ci return 0; 1529c87c5fbaSopenharmony_ci} 1530c87c5fbaSopenharmony_ci 1531c87c5fbaSopenharmony_ci/* 1532c87c5fbaSopenharmony_ci * The struct hmac_algs and the function get_hmac_alg() are used to 1533c87c5fbaSopenharmony_ci * determine which hmac type to use for creating the required hmac 1534c87c5fbaSopenharmony_ci * suite object. 1535c87c5fbaSopenharmony_ci */ 1536c87c5fbaSopenharmony_cistatic struct hmac_algs { 1537c87c5fbaSopenharmony_ci cose_hmac_alg_t hmac_alg; 1538c87c5fbaSopenharmony_ci u_int hmac_type; 1539c87c5fbaSopenharmony_ci} hmacs[] = { 1540c87c5fbaSopenharmony_ci {COSE_HMAC_ALG_HMAC256_256, 1}, 1541c87c5fbaSopenharmony_ci}; 1542c87c5fbaSopenharmony_ci 1543c87c5fbaSopenharmony_cistatic u_int 1544c87c5fbaSopenharmony_ciget_hmac_alg(cose_hmac_alg_t hmac_alg) { 1545c87c5fbaSopenharmony_ci size_t idx; 1546c87c5fbaSopenharmony_ci 1547c87c5fbaSopenharmony_ci for (idx = 0; idx < sizeof(hmacs)/sizeof(struct hmac_algs); idx++) { 1548c87c5fbaSopenharmony_ci if (hmacs[idx].hmac_alg == hmac_alg) 1549c87c5fbaSopenharmony_ci return hmacs[idx].hmac_type; 1550c87c5fbaSopenharmony_ci } 1551c87c5fbaSopenharmony_ci coap_log_debug("get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg); 1552c87c5fbaSopenharmony_ci return 0; 1553c87c5fbaSopenharmony_ci} 1554c87c5fbaSopenharmony_ci 1555c87c5fbaSopenharmony_ciint 1556c87c5fbaSopenharmony_cicoap_crypto_check_cipher_alg(cose_alg_t alg) { 1557c87c5fbaSopenharmony_ci return get_cipher_alg(alg); 1558c87c5fbaSopenharmony_ci} 1559c87c5fbaSopenharmony_ci 1560c87c5fbaSopenharmony_ciint 1561c87c5fbaSopenharmony_cicoap_crypto_check_hkdf_alg(cose_hkdf_alg_t hkdf_alg) { 1562c87c5fbaSopenharmony_ci cose_hmac_alg_t hmac_alg; 1563c87c5fbaSopenharmony_ci 1564c87c5fbaSopenharmony_ci if (!cose_get_hmac_alg_for_hkdf(hkdf_alg, &hmac_alg)) 1565c87c5fbaSopenharmony_ci return 0; 1566c87c5fbaSopenharmony_ci return get_hmac_alg(hmac_alg); 1567c87c5fbaSopenharmony_ci} 1568c87c5fbaSopenharmony_ci 1569c87c5fbaSopenharmony_ciint 1570c87c5fbaSopenharmony_cicoap_crypto_aead_encrypt(const coap_crypto_param_t *params, 1571c87c5fbaSopenharmony_ci coap_bin_const_t *data, 1572c87c5fbaSopenharmony_ci coap_bin_const_t *aad, 1573c87c5fbaSopenharmony_ci uint8_t *result, size_t *max_result_len) { 1574c87c5fbaSopenharmony_ci int num_bytes; 1575c87c5fbaSopenharmony_ci const coap_crypto_aes_ccm_t *ccm; 1576c87c5fbaSopenharmony_ci dtls_ccm_params_t dtls_params; 1577c87c5fbaSopenharmony_ci coap_bin_const_t laad; 1578c87c5fbaSopenharmony_ci 1579c87c5fbaSopenharmony_ci if (data == NULL) 1580c87c5fbaSopenharmony_ci return 0; 1581c87c5fbaSopenharmony_ci 1582c87c5fbaSopenharmony_ci assert(params); 1583c87c5fbaSopenharmony_ci 1584c87c5fbaSopenharmony_ci if (get_cipher_alg(params->alg) == 0) { 1585c87c5fbaSopenharmony_ci coap_log_debug("coap_crypto_encrypt: algorithm %d not supported\n", 1586c87c5fbaSopenharmony_ci params->alg); 1587c87c5fbaSopenharmony_ci return 0; 1588c87c5fbaSopenharmony_ci } 1589c87c5fbaSopenharmony_ci 1590c87c5fbaSopenharmony_ci ccm = ¶ms->params.aes; 1591c87c5fbaSopenharmony_ci if (*max_result_len < (data->length + ccm->tag_len)) { 1592c87c5fbaSopenharmony_ci coap_log_warn("coap_encrypt: result buffer too small\n"); 1593c87c5fbaSopenharmony_ci return 0; 1594c87c5fbaSopenharmony_ci } 1595c87c5fbaSopenharmony_ci 1596c87c5fbaSopenharmony_ci dtls_params.nonce = ccm->nonce; 1597c87c5fbaSopenharmony_ci dtls_params.tag_length = ccm->tag_len; 1598c87c5fbaSopenharmony_ci dtls_params.l = ccm->l; 1599c87c5fbaSopenharmony_ci 1600c87c5fbaSopenharmony_ci if (aad) { 1601c87c5fbaSopenharmony_ci laad = *aad; 1602c87c5fbaSopenharmony_ci } else { 1603c87c5fbaSopenharmony_ci laad.s = NULL; 1604c87c5fbaSopenharmony_ci laad.length = 0; 1605c87c5fbaSopenharmony_ci } 1606c87c5fbaSopenharmony_ci 1607c87c5fbaSopenharmony_ci num_bytes = dtls_encrypt_params(&dtls_params, 1608c87c5fbaSopenharmony_ci data->s, data->length, 1609c87c5fbaSopenharmony_ci result, 1610c87c5fbaSopenharmony_ci ccm->key.s, ccm->key.length, 1611c87c5fbaSopenharmony_ci laad.s, laad.length); 1612c87c5fbaSopenharmony_ci if (num_bytes < 0) { 1613c87c5fbaSopenharmony_ci return 0; 1614c87c5fbaSopenharmony_ci } 1615c87c5fbaSopenharmony_ci *max_result_len = num_bytes; 1616c87c5fbaSopenharmony_ci return 1; 1617c87c5fbaSopenharmony_ci} 1618c87c5fbaSopenharmony_ci 1619c87c5fbaSopenharmony_ciint 1620c87c5fbaSopenharmony_cicoap_crypto_aead_decrypt(const coap_crypto_param_t *params, 1621c87c5fbaSopenharmony_ci coap_bin_const_t *data, 1622c87c5fbaSopenharmony_ci coap_bin_const_t *aad, 1623c87c5fbaSopenharmony_ci uint8_t *result, size_t *max_result_len) { 1624c87c5fbaSopenharmony_ci int num_bytes; 1625c87c5fbaSopenharmony_ci const coap_crypto_aes_ccm_t *ccm; 1626c87c5fbaSopenharmony_ci dtls_ccm_params_t dtls_params; 1627c87c5fbaSopenharmony_ci coap_bin_const_t laad; 1628c87c5fbaSopenharmony_ci 1629c87c5fbaSopenharmony_ci if (data == NULL) 1630c87c5fbaSopenharmony_ci return 0; 1631c87c5fbaSopenharmony_ci 1632c87c5fbaSopenharmony_ci assert(params); 1633c87c5fbaSopenharmony_ci 1634c87c5fbaSopenharmony_ci if (get_cipher_alg(params->alg) == 0) { 1635c87c5fbaSopenharmony_ci coap_log_debug("coap_crypto_decrypt: algorithm %d not supported\n", 1636c87c5fbaSopenharmony_ci params->alg); 1637c87c5fbaSopenharmony_ci return 0; 1638c87c5fbaSopenharmony_ci } 1639c87c5fbaSopenharmony_ci 1640c87c5fbaSopenharmony_ci ccm = ¶ms->params.aes; 1641c87c5fbaSopenharmony_ci 1642c87c5fbaSopenharmony_ci if ((*max_result_len + ccm->tag_len) < data->length) { 1643c87c5fbaSopenharmony_ci coap_log_warn("coap_decrypt: result buffer too small\n"); 1644c87c5fbaSopenharmony_ci return 0; 1645c87c5fbaSopenharmony_ci } 1646c87c5fbaSopenharmony_ci 1647c87c5fbaSopenharmony_ci dtls_params.nonce = ccm->nonce; 1648c87c5fbaSopenharmony_ci dtls_params.tag_length = ccm->tag_len; 1649c87c5fbaSopenharmony_ci dtls_params.l = ccm->l; 1650c87c5fbaSopenharmony_ci 1651c87c5fbaSopenharmony_ci if (aad) { 1652c87c5fbaSopenharmony_ci laad = *aad; 1653c87c5fbaSopenharmony_ci } else { 1654c87c5fbaSopenharmony_ci laad.s = NULL; 1655c87c5fbaSopenharmony_ci laad.length = 0; 1656c87c5fbaSopenharmony_ci } 1657c87c5fbaSopenharmony_ci 1658c87c5fbaSopenharmony_ci num_bytes = dtls_decrypt_params(&dtls_params, 1659c87c5fbaSopenharmony_ci data->s, data->length, 1660c87c5fbaSopenharmony_ci result, 1661c87c5fbaSopenharmony_ci ccm->key.s, ccm->key.length, 1662c87c5fbaSopenharmony_ci laad.s, laad.length); 1663c87c5fbaSopenharmony_ci if (num_bytes < 0) { 1664c87c5fbaSopenharmony_ci return 0; 1665c87c5fbaSopenharmony_ci } 1666c87c5fbaSopenharmony_ci *max_result_len = num_bytes; 1667c87c5fbaSopenharmony_ci return 1; 1668c87c5fbaSopenharmony_ci} 1669c87c5fbaSopenharmony_ci 1670c87c5fbaSopenharmony_ciint 1671c87c5fbaSopenharmony_cicoap_crypto_hmac(cose_hmac_alg_t hmac_alg, coap_bin_const_t *key, 1672c87c5fbaSopenharmony_ci coap_bin_const_t *data, coap_bin_const_t **hmac) { 1673c87c5fbaSopenharmony_ci dtls_hmac_context_t hmac_context; 1674c87c5fbaSopenharmony_ci int num_bytes; 1675c87c5fbaSopenharmony_ci coap_binary_t *dummy; 1676c87c5fbaSopenharmony_ci 1677c87c5fbaSopenharmony_ci if (data == NULL) 1678c87c5fbaSopenharmony_ci return 0; 1679c87c5fbaSopenharmony_ci 1680c87c5fbaSopenharmony_ci if (get_hmac_alg(hmac_alg) == 0) { 1681c87c5fbaSopenharmony_ci coap_log_debug("coap_crypto_hmac: algorithm %d not supported\n", hmac_alg); 1682c87c5fbaSopenharmony_ci return 0; 1683c87c5fbaSopenharmony_ci } 1684c87c5fbaSopenharmony_ci 1685c87c5fbaSopenharmony_ci dummy = coap_new_binary(DTLS_SHA256_DIGEST_LENGTH); 1686c87c5fbaSopenharmony_ci if (dummy == NULL) 1687c87c5fbaSopenharmony_ci return 0; 1688c87c5fbaSopenharmony_ci 1689c87c5fbaSopenharmony_ci dtls_hmac_init(&hmac_context, key->s, key->length); 1690c87c5fbaSopenharmony_ci dtls_hmac_update(&hmac_context, data->s, data->length); 1691c87c5fbaSopenharmony_ci num_bytes = dtls_hmac_finalize(&hmac_context, dummy->s); 1692c87c5fbaSopenharmony_ci 1693c87c5fbaSopenharmony_ci if (num_bytes != DTLS_SHA256_DIGEST_LENGTH) { 1694c87c5fbaSopenharmony_ci coap_delete_binary(dummy); 1695c87c5fbaSopenharmony_ci return 0; 1696c87c5fbaSopenharmony_ci } 1697c87c5fbaSopenharmony_ci *hmac = (coap_bin_const_t *)dummy; 1698c87c5fbaSopenharmony_ci return 1; 1699c87c5fbaSopenharmony_ci} 1700c87c5fbaSopenharmony_ci 1701c87c5fbaSopenharmony_ci#endif /* COAP_OSCORE_SUPPORT */ 1702c87c5fbaSopenharmony_ci 1703c87c5fbaSopenharmony_ci#else /* !COAP_WITH_LIBTINYDTLS */ 1704c87c5fbaSopenharmony_ci 1705c87c5fbaSopenharmony_ci#ifdef __clang__ 1706c87c5fbaSopenharmony_ci/* Make compilers happy that do not like empty modules. As this function is 1707c87c5fbaSopenharmony_ci * never used, we ignore -Wunused-function at the end of compiling this file 1708c87c5fbaSopenharmony_ci */ 1709c87c5fbaSopenharmony_ci#pragma GCC diagnostic ignored "-Wunused-function" 1710c87c5fbaSopenharmony_ci#endif 1711c87c5fbaSopenharmony_cistatic inline void 1712c87c5fbaSopenharmony_cidummy(void) { 1713c87c5fbaSopenharmony_ci} 1714c87c5fbaSopenharmony_ci 1715c87c5fbaSopenharmony_ci#endif /* COAP_WITH_LIBTINYDTLS */ 1716