1/* 2 * coap_openssl.c -- Datagram Transport Layer Support for libcoap with openssl 3 * 4 * Copyright (C) 2017 Jean-Claude Michelou <jcm@spinetix.com> 5 * Copyright (C) 2018-2023 Jon Shallow <supjps-libcoap@jpshallow.com> 6 * 7 * SPDX-License-Identifier: BSD-2-Clause 8 * 9 * This file is part of the CoAP library libcoap. Please see README for terms 10 * of use. 11 */ 12 13/** 14 * @file coap_openssl.c 15 * @brief OpenSSL specific interface functions. 16 */ 17 18#include "coap3/coap_internal.h" 19 20#ifdef COAP_WITH_LIBOPENSSL 21 22/* 23 * OpenSSL 1.1.0 has support for making decisions during receipt of 24 * the Client Hello - the call back function is set up using 25 * SSL_CTX_set_tlsext_servername_callback() which is called later in the 26 * Client Hello processing - but called every Client Hello. 27 * Certificates and Preshared Keys have to be set up in the SSL CTX before 28 * SSL_accept() is called, making the code messy to decide whether this is a 29 * PKI or PSK incoming request to handle things accordingly if both are 30 * defined. SNI has to create a new SSL CTX to handle different server names 31 * with different crtificates. 32 * 33 * OpenSSL 1.1.1 introduces a new function SSL_CTX_set_client_hello_cb(). 34 * The call back is invoked early on in the Client Hello processing giving 35 * the ability to easily use different Preshared Keys, Certificates etc. 36 * Certificates do not have to be set up in the SSL CTX before SSL_Accept is 37 * called. 38 * Later in the Client Hello code, the callback for 39 * SSL_CTX_set_tlsext_servername_callback() is still called, but only if SNI 40 * is being used by the client, so cannot be used for doing things the 41 * OpenSSL 1.1.0 way. 42 * 43 * OpenSSL 1.1.1 supports TLS1.3. 44 * 45 * Consequently, this code has to have compile time options to include / 46 * exclude code based on whether compiled against 1.1.0 or 1.1.1, as well as 47 * have additional run time checks. 48 * 49 * It is possible to override the Ciphers, define the Algorithms or Groups 50 * to use for the SSL negotiations at compile time. This is done by the adding 51 * of the appropriate -D option to the CPPFLAGS parameter that is used on the 52 * ./configure command line. 53 * E.g. ./configure CPPFLAGS="-DXX=\"YY\" -DUU=\"VV\"" 54 * The parameter value is case-sensitive. 55 * 56 * The ciphers can be overridden with (example) 57 * -DCOAP_OPENSSL_CIPHERS=\"ECDHE-ECDSA-AES256-GCM-SHA384\" 58 * 59 * The Algorithms can be defined by (example) 60 * -DCOAP_OPENSSL_SIGALGS=\"ed25519\" 61 * 62 * The Groups (OpenSSL 1.1.1 or later) can be defined by (example) 63 * -DCOAP_OPENSSL_GROUPS=\"X25519\" 64 * 65 */ 66#include <openssl/ssl.h> 67#include <openssl/engine.h> 68#include <openssl/err.h> 69#include <openssl/rand.h> 70#include <openssl/hmac.h> 71#include <openssl/x509v3.h> 72 73#if OPENSSL_VERSION_NUMBER >= 0x30000000L 74#ifdef __GNUC__ 75/* Ignore OpenSSL 3.0 deprecated warnings for now */ 76#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 77#endif 78#if defined(_WIN32) 79#if !defined(__MINGW32__) 80#pragma warning(disable : 4996) 81#endif /* ! __MINGW32__ */ 82#endif /* _WIN32 */ 83#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ 84 85#ifdef COAP_EPOLL_SUPPORT 86# include <sys/epoll.h> 87#endif /* COAP_EPOLL_SUPPORT */ 88 89#if OPENSSL_VERSION_NUMBER < 0x10100000L 90#error Must be compiled against OpenSSL 1.1.0 or later 91#endif 92 93#ifdef _WIN32 94#define strcasecmp _stricmp 95#define strncasecmp _strnicmp 96#endif 97 98/* RFC6091/RFC7250 */ 99#ifndef TLSEXT_TYPE_client_certificate_type 100#define TLSEXT_TYPE_client_certificate_type 19 101#endif 102#ifndef TLSEXT_TYPE_server_certificate_type 103#define TLSEXT_TYPE_server_certificate_type 20 104#endif 105 106#ifndef COAP_OPENSSL_CIPHERS 107#if OPENSSL_VERSION_NUMBER >= 0x10101000L 108#define COAP_OPENSSL_CIPHERS "TLSv1.3:TLSv1.2:!NULL" 109#else /* OPENSSL_VERSION_NUMBER < 0x10101000L */ 110#define COAP_OPENSSL_CIPHERS "TLSv1.2:!NULL" 111#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ 112#endif /*COAP_OPENSSL_CIPHERS */ 113 114#ifndef COAP_OPENSSL_PSK_CIPHERS 115#define COAP_OPENSSL_PSK_CIPHERS "PSK:!NULL" 116#endif /*COAP_OPENSSL_PSK_CIPHERS */ 117 118/* This structure encapsulates the OpenSSL context object. */ 119typedef struct coap_dtls_context_t { 120 SSL_CTX *ctx; 121 SSL *ssl; /* OpenSSL object for listening to connection requests */ 122 HMAC_CTX *cookie_hmac; 123 BIO_METHOD *meth; 124 BIO_ADDR *bio_addr; 125} coap_dtls_context_t; 126 127typedef struct coap_tls_context_t { 128 SSL_CTX *ctx; 129 BIO_METHOD *meth; 130} coap_tls_context_t; 131 132#define IS_PSK 0x1 133#define IS_PKI 0x2 134 135typedef struct sni_entry { 136 char *sni; 137#if OPENSSL_VERSION_NUMBER < 0x10101000L 138 SSL_CTX *ctx; 139#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 140 coap_dtls_key_t pki_key; 141#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 142} sni_entry; 143 144typedef struct psk_sni_entry { 145 char *sni; 146#if OPENSSL_VERSION_NUMBER < 0x10101000L 147 SSL_CTX *ctx; 148#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ 149 coap_dtls_spsk_info_t psk_info; 150} psk_sni_entry; 151 152typedef struct coap_openssl_context_t { 153 coap_dtls_context_t dtls; 154#if !COAP_DISABLE_TCP 155 coap_tls_context_t tls; 156#endif /* !COAP_DISABLE_TCP */ 157 coap_dtls_pki_t setup_data; 158 int psk_pki_enabled; 159 size_t sni_count; 160 sni_entry *sni_entry_list; 161 size_t psk_sni_count; 162 psk_sni_entry *psk_sni_entry_list; 163} coap_openssl_context_t; 164 165#if COAP_SERVER_SUPPORT 166#if OPENSSL_VERSION_NUMBER < 0x10101000L 167static int psk_tls_server_name_call_back(SSL *ssl, int *sd, void *arg); 168#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 169static int psk_tls_client_hello_call_back(SSL *ssl, int *al, void *arg); 170#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 171#endif /* COAP_SERVER_SUPPORT */ 172 173int 174coap_dtls_is_supported(void) { 175 if (SSLeay() < 0x10100000L) { 176 coap_log_warn("OpenSSL version 1.1.0 or later is required\n"); 177 return 0; 178 } 179#if OPENSSL_VERSION_NUMBER >= 0x10101000L 180 /* 181 * For 1.1.1, we need to use SSL_CTX_set_client_hello_cb() 182 * which is not in 1.1.0 instead of SSL_CTX_set_tlsext_servername_callback() 183 * 184 * However, there could be a runtime undefined external reference error 185 * as SSL_CTX_set_client_hello_cb() is not there in 1.1.0. 186 */ 187 if (SSLeay() < 0x10101000L) { 188 coap_log_warn("OpenSSL version 1.1.1 or later is required\n"); 189 return 0; 190 } 191#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 192 return 1; 193} 194 195int 196coap_tls_is_supported(void) { 197#if !COAP_DISABLE_TCP 198 if (SSLeay() < 0x10100000L) { 199 coap_log_warn("OpenSSL version 1.1.0 or later is required\n"); 200 return 0; 201 } 202#if OPENSSL_VERSION_NUMBER >= 0x10101000L 203 if (SSLeay() < 0x10101000L) { 204 coap_log_warn("OpenSSL version 1.1.1 or later is required\n"); 205 return 0; 206 } 207#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 208 return 1; 209#else /* COAP_DISABLE_TCP */ 210 return 0; 211#endif /* COAP_DISABLE_TCP */ 212} 213 214/* 215 * return 0 failed 216 * 1 passed 217 */ 218int 219coap_dtls_psk_is_supported(void) { 220 return 1; 221} 222 223/* 224 * return 0 failed 225 * 1 passed 226 */ 227int 228coap_dtls_pki_is_supported(void) { 229 return 1; 230} 231 232/* 233 * return 0 failed 234 * 1 passed 235 */ 236int 237coap_dtls_pkcs11_is_supported(void) { 238 return 1; 239} 240 241/* 242 * return 0 failed 243 * 1 passed 244 */ 245int 246coap_dtls_rpk_is_supported(void) { 247 return 0; 248} 249 250coap_tls_version_t * 251coap_get_tls_library_version(void) { 252 static coap_tls_version_t version; 253 version.version = SSLeay(); 254 version.built_version = OPENSSL_VERSION_NUMBER; 255 version.type = COAP_TLS_LIBRARY_OPENSSL; 256 return &version; 257} 258 259static ENGINE *ssl_engine = NULL; 260 261void 262coap_dtls_startup(void) { 263 SSL_load_error_strings(); 264 SSL_library_init(); 265 ENGINE_load_dynamic(); 266} 267 268void 269coap_dtls_shutdown(void) { 270 if (ssl_engine) { 271 /* Release the functional reference from ENGINE_init() */ 272 ENGINE_finish(ssl_engine); 273 /* Release the structural reference from ENGINE_by_id() */ 274 ENGINE_free(ssl_engine); 275 ssl_engine = NULL; 276 } 277 ERR_free_strings(); 278 coap_dtls_set_log_level(COAP_LOG_EMERG); 279} 280 281void * 282coap_dtls_get_tls(const coap_session_t *c_session, 283 coap_tls_library_t *tls_lib) { 284 if (tls_lib) 285 *tls_lib = COAP_TLS_LIBRARY_OPENSSL; 286 if (c_session) { 287 return c_session->tls; 288 } 289 return NULL; 290} 291 292/* 293 * Logging levels use the standard CoAP logging levels 294 */ 295static coap_log_t dtls_log_level = COAP_LOG_EMERG; 296 297void 298coap_dtls_set_log_level(coap_log_t level) { 299 dtls_log_level = level; 300} 301 302coap_log_t 303coap_dtls_get_log_level(void) { 304 return dtls_log_level; 305} 306 307typedef struct coap_ssl_st { 308 coap_session_t *session; 309 const void *pdu; 310 unsigned pdu_len; 311 unsigned peekmode; 312 coap_tick_t timeout; 313} coap_ssl_data; 314 315static int 316coap_dgram_create(BIO *a) { 317 coap_ssl_data *data = NULL; 318 data = malloc(sizeof(coap_ssl_data)); 319 if (data == NULL) 320 return 0; 321 BIO_set_init(a, 1); 322 BIO_set_data(a, data); 323 memset(data, 0x00, sizeof(coap_ssl_data)); 324 return 1; 325} 326 327static int 328coap_dgram_destroy(BIO *a) { 329 coap_ssl_data *data; 330 if (a == NULL) 331 return 0; 332 data = (coap_ssl_data *)BIO_get_data(a); 333 if (data != NULL) 334 free(data); 335 return 1; 336} 337 338static int 339coap_dgram_read(BIO *a, char *out, int outl) { 340 int ret = 0; 341 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a); 342 343 if (out != NULL) { 344 if (data != NULL && data->pdu_len > 0) { 345 if (outl < (int)data->pdu_len) { 346 memcpy(out, data->pdu, outl); 347 ret = outl; 348 } else { 349 memcpy(out, data->pdu, data->pdu_len); 350 ret = (int)data->pdu_len; 351 } 352 if (!data->peekmode) { 353 data->pdu_len = 0; 354 data->pdu = NULL; 355 } 356 } else { 357 ret = -1; 358 } 359 BIO_clear_retry_flags(a); 360 if (ret < 0) 361 BIO_set_retry_read(a); 362 } 363 return ret; 364} 365 366static int 367coap_dgram_write(BIO *a, const char *in, int inl) { 368 int ret = 0; 369 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a); 370 371 if (data->session) { 372 if (!coap_netif_available(data->session) 373#if COAP_SERVER_SUPPORT 374 && data->session->endpoint == NULL 375#endif /* COAP_SERVER_SUPPORT */ 376 ) { 377 /* socket was closed on client due to error */ 378 BIO_clear_retry_flags(a); 379 errno = ECONNRESET; 380 return -1; 381 } 382 ret = (int)data->session->sock.lfunc[COAP_LAYER_TLS].l_write(data->session, 383 (const uint8_t *)in, 384 inl); 385 BIO_clear_retry_flags(a); 386 if (ret <= 0) 387 BIO_set_retry_write(a); 388 } else { 389 BIO_clear_retry_flags(a); 390 ret = -1; 391 } 392 return ret; 393} 394 395static int 396coap_dgram_puts(BIO *a, const char *pstr) { 397 return coap_dgram_write(a, pstr, (int)strlen(pstr)); 398} 399 400static long 401coap_dgram_ctrl(BIO *a, int cmd, long num, void *ptr) { 402 long ret = 1; 403 coap_ssl_data *data = BIO_get_data(a); 404 405 (void)ptr; 406 407 switch (cmd) { 408 case BIO_CTRL_GET_CLOSE: 409 ret = BIO_get_shutdown(a); 410 break; 411 case BIO_CTRL_SET_CLOSE: 412 BIO_set_shutdown(a, (int)num); 413 ret = 1; 414 break; 415 case BIO_CTRL_DGRAM_SET_PEEK_MODE: 416 data->peekmode = (unsigned)num; 417 break; 418 case BIO_CTRL_DGRAM_CONNECT: 419 case BIO_C_SET_FD: 420 case BIO_C_GET_FD: 421 case BIO_CTRL_DGRAM_SET_DONT_FRAG: 422 case BIO_CTRL_DGRAM_GET_MTU: 423 case BIO_CTRL_DGRAM_SET_MTU: 424 case BIO_CTRL_DGRAM_QUERY_MTU: 425 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: 426 ret = -1; 427 break; 428 case BIO_CTRL_DUP: 429 case BIO_CTRL_FLUSH: 430 case BIO_CTRL_DGRAM_MTU_DISCOVER: 431 case BIO_CTRL_DGRAM_SET_CONNECTED: 432 ret = 1; 433 break; 434 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: 435 data->timeout = coap_ticks_from_rt_us((uint64_t)((struct timeval *)ptr)->tv_sec * 1000000 + (( 436 struct timeval *)ptr)->tv_usec); 437 ret = 1; 438 break; 439 case BIO_CTRL_RESET: 440 case BIO_C_FILE_SEEK: 441 case BIO_C_FILE_TELL: 442 case BIO_CTRL_INFO: 443 case BIO_CTRL_PENDING: 444 case BIO_CTRL_WPENDING: 445 case BIO_CTRL_DGRAM_GET_PEER: 446 case BIO_CTRL_DGRAM_SET_PEER: 447 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: 448 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: 449 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: 450 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: 451 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: 452 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: 453 case BIO_CTRL_DGRAM_MTU_EXCEEDED: 454 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: 455 default: 456 ret = 0; 457 break; 458 } 459 return ret; 460} 461 462static int 463coap_dtls_generate_cookie(SSL *ssl, 464 unsigned char *cookie, 465 unsigned int *cookie_len) { 466 coap_dtls_context_t *dtls = 467 (coap_dtls_context_t *)SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)); 468 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl)); 469 int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL); 470 r &= HMAC_Update(dtls->cookie_hmac, 471 (const uint8_t *)&data->session->addr_info.local.addr, 472 (size_t)data->session->addr_info.local.size); 473 r &= HMAC_Update(dtls->cookie_hmac, 474 (const uint8_t *)&data->session->addr_info.remote.addr, 475 (size_t)data->session->addr_info.remote.size); 476 r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len); 477 return r; 478} 479 480static int 481coap_dtls_verify_cookie(SSL *ssl, 482 const uint8_t *cookie, 483 unsigned int cookie_len) { 484 uint8_t hmac[32]; 485 unsigned len = 32; 486 if (coap_dtls_generate_cookie(ssl, hmac, &len) && 487 cookie_len == len && memcmp(cookie, hmac, len) == 0) 488 return 1; 489 else 490 return 0; 491} 492 493#if COAP_CLIENT_SUPPORT 494static unsigned int 495coap_dtls_psk_client_callback(SSL *ssl, 496 const char *hint, 497 char *identity, 498 unsigned int max_identity_len, 499 unsigned char *psk, 500 unsigned int max_psk_len) { 501 coap_session_t *c_session; 502 coap_openssl_context_t *o_context; 503 coap_dtls_cpsk_t *setup_data; 504 coap_bin_const_t temp; 505 const coap_dtls_cpsk_info_t *cpsk_info; 506 const coap_bin_const_t *psk_key; 507 const coap_bin_const_t *psk_identity; 508 509 c_session = (coap_session_t *)SSL_get_app_data(ssl); 510 if (c_session == NULL) 511 return 0; 512 o_context = (coap_openssl_context_t *)c_session->context->dtls_context; 513 if (o_context == NULL) 514 return 0; 515 setup_data = &c_session->cpsk_setup_data; 516 517 temp.s = hint ? (const uint8_t *)hint : (const uint8_t *)""; 518 temp.length = strlen((const char *)temp.s); 519 coap_session_refresh_psk_hint(c_session, &temp); 520 521 coap_log_debug("got psk_identity_hint: '%.*s'\n", (int)temp.length, 522 (const char *)temp.s); 523 524 if (setup_data->validate_ih_call_back) { 525 coap_str_const_t lhint; 526 527 lhint.s = temp.s; 528 lhint.length = temp.length; 529 cpsk_info = 530 setup_data->validate_ih_call_back(&lhint, 531 c_session, 532 setup_data->ih_call_back_arg); 533 534 if (cpsk_info == NULL) 535 return 0; 536 537 coap_session_refresh_psk_identity(c_session, &cpsk_info->identity); 538 coap_session_refresh_psk_key(c_session, &cpsk_info->key); 539 psk_identity = &cpsk_info->identity; 540 psk_key = &cpsk_info->key; 541 } else { 542 psk_identity = coap_get_session_client_psk_identity(c_session); 543 psk_key = coap_get_session_client_psk_key(c_session); 544 } 545 546 if (psk_identity == NULL || psk_key == NULL) { 547 coap_log_warn("no PSK available\n"); 548 return 0; 549 } 550 551 /* identity has to be NULL terminated */ 552 if (!max_identity_len) 553 return 0; 554 max_identity_len--; 555 if (psk_identity->length > max_identity_len) { 556 coap_log_warn("psk_identity too large, truncated to %d bytes\n", 557 max_identity_len); 558 } else { 559 /* Reduce to match */ 560 max_identity_len = (unsigned int)psk_identity->length; 561 } 562 memcpy(identity, psk_identity->s, max_identity_len); 563 identity[max_identity_len] = '\000'; 564 565 if (psk_key->length > max_psk_len) { 566 coap_log_warn("psk_key too large, truncated to %d bytes\n", 567 max_psk_len); 568 } else { 569 /* Reduce to match */ 570 max_psk_len = (unsigned int)psk_key->length; 571 } 572 memcpy(psk, psk_key->s, max_psk_len); 573 return max_psk_len; 574} 575#endif /* COAP_CLIENT_SUPPORT */ 576 577#if COAP_SERVER_SUPPORT 578static unsigned int 579coap_dtls_psk_server_callback( 580 SSL *ssl, 581 const char *identity, 582 unsigned char *psk, 583 unsigned int max_psk_len 584) { 585 coap_session_t *c_session; 586 coap_dtls_spsk_t *setup_data; 587 coap_bin_const_t lidentity; 588 const coap_bin_const_t *psk_key; 589 590 c_session = (coap_session_t *)SSL_get_app_data(ssl); 591 if (c_session == NULL) 592 return 0; 593 594 setup_data = &c_session->context->spsk_setup_data; 595 596 /* Track the Identity being used */ 597 lidentity.s = identity ? (const uint8_t *)identity : (const uint8_t *)""; 598 lidentity.length = strlen((const char *)lidentity.s); 599 coap_session_refresh_psk_identity(c_session, &lidentity); 600 601 coap_log_debug("got psk_identity: '%.*s'\n", 602 (int)lidentity.length, (const char *)lidentity.s); 603 604 if (setup_data->validate_id_call_back) { 605 psk_key = setup_data->validate_id_call_back(&lidentity, 606 c_session, 607 setup_data->id_call_back_arg); 608 609 coap_session_refresh_psk_key(c_session, psk_key); 610 } else { 611 psk_key = coap_get_session_server_psk_key(c_session); 612 } 613 614 if (psk_key == NULL) 615 return 0; 616 617 if (psk_key->length > max_psk_len) { 618 coap_log_warn("psk_key too large, truncated to %d bytes\n", 619 max_psk_len); 620 } else { 621 /* Reduce to match */ 622 max_psk_len = (unsigned int)psk_key->length; 623 } 624 memcpy(psk, psk_key->s, max_psk_len); 625 return max_psk_len; 626} 627#endif /* COAP_SERVER_SUPPORT */ 628 629static const char * 630ssl_function_definition(unsigned long e) { 631#if OPENSSL_VERSION_NUMBER >= 0x30000000L 632 (void)e; 633 return ""; 634#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 635 static char buff[80]; 636 637 snprintf(buff, sizeof(buff), " at %s:%s", 638 ERR_lib_error_string(e), ERR_func_error_string(e)); 639 return buff; 640#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 641} 642 643static void 644coap_dtls_info_callback(const SSL *ssl, int where, int ret) { 645 coap_session_t *session = (coap_session_t *)SSL_get_app_data(ssl); 646 const char *pstr; 647 int w = where &~SSL_ST_MASK; 648 649 if (w & SSL_ST_CONNECT) 650 pstr = "SSL_connect"; 651 else if (w & SSL_ST_ACCEPT) 652 pstr = "SSL_accept"; 653 else 654 pstr = "undefined"; 655 656 if (where & SSL_CB_LOOP) { 657 coap_dtls_log(COAP_LOG_DEBUG, "* %s: %s:%s\n", 658 coap_session_str(session), pstr, SSL_state_string_long(ssl)); 659 } else if (where & SSL_CB_ALERT) { 660 coap_log_t log_level = COAP_LOG_INFO; 661 pstr = (where & SSL_CB_READ) ? "read" : "write"; 662 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL) { 663 session->dtls_event = COAP_EVENT_DTLS_ERROR; 664 if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY) 665 log_level = COAP_LOG_WARN; 666 } 667 /* Need to let CoAP logging know why this session is dying */ 668 coap_log(log_level, "* %s: SSL3 alert %s:%s:%s\n", 669 coap_session_str(session), 670 pstr, 671 SSL_alert_type_string_long(ret), 672 SSL_alert_desc_string_long(ret)); 673 } else if (where & SSL_CB_EXIT) { 674 if (ret == 0) { 675 if (dtls_log_level >= COAP_LOG_WARN) { 676 unsigned long e; 677 coap_dtls_log(COAP_LOG_WARN, "* %s: %s:failed in %s\n", 678 coap_session_str(session), pstr, SSL_state_string_long(ssl)); 679 while ((e = ERR_get_error())) 680 coap_dtls_log(COAP_LOG_WARN, "* %s: %s%s\n", 681 coap_session_str(session), ERR_reason_error_string(e), 682 ssl_function_definition(e)); 683 } 684 } else if (ret < 0) { 685 if (dtls_log_level >= COAP_LOG_WARN) { 686 int err = SSL_get_error(ssl, ret); 687 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE && 688 err != SSL_ERROR_WANT_CONNECT && err != SSL_ERROR_WANT_ACCEPT && 689 err != SSL_ERROR_WANT_X509_LOOKUP) { 690 long e; 691 coap_dtls_log(COAP_LOG_WARN, "* %s: %s:error in %s\n", 692 coap_session_str(session), pstr, SSL_state_string_long(ssl)); 693 while ((e = ERR_get_error())) 694 coap_dtls_log(COAP_LOG_WARN, "* %s: %s%s\n", 695 coap_session_str(session), ERR_reason_error_string(e), 696 ssl_function_definition(e)); 697 } 698 } 699 } 700 } 701 702 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK) 703 session->dtls_event = COAP_EVENT_DTLS_RENEGOTIATE; 704} 705 706#if !COAP_DISABLE_TCP 707static int 708coap_sock_create(BIO *a) { 709 BIO_set_init(a, 1); 710 return 1; 711} 712 713static int 714coap_sock_destroy(BIO *a) { 715 (void)a; 716 return 1; 717} 718 719/* 720 * strm 721 * return +ve data amount 722 * 0 no more 723 * -1 error 724 */ 725static int 726coap_sock_read(BIO *a, char *out, int outl) { 727 int ret = 0; 728 coap_session_t *session = (coap_session_t *)BIO_get_data(a); 729 730 if (out != NULL) { 731 ret =(int)session->sock.lfunc[COAP_LAYER_TLS].l_read(session, (u_char *)out, 732 outl); 733 /* Translate layer returns into what OpenSSL expects */ 734 if (ret == 0) { 735 BIO_set_retry_read(a); 736 ret = -1; 737 } else { 738 BIO_clear_retry_flags(a); 739 } 740 } 741 return ret; 742} 743 744/* 745 * strm 746 * return +ve data amount 747 * 0 no more 748 * -1 error (error in errno) 749 */ 750static int 751coap_sock_write(BIO *a, const char *in, int inl) { 752 int ret = 0; 753 coap_session_t *session = (coap_session_t *)BIO_get_data(a); 754 755 ret = (int)session->sock.lfunc[COAP_LAYER_TLS].l_write(session, 756 (const uint8_t *)in, 757 inl); 758 /* Translate layer what returns into what OpenSSL expects */ 759 BIO_clear_retry_flags(a); 760 if (ret == 0) { 761 BIO_set_retry_read(a); 762 ret = -1; 763 } else { 764 BIO_clear_retry_flags(a); 765 if (ret == -1) { 766 if ((session->state == COAP_SESSION_STATE_CSM || 767 session->state == COAP_SESSION_STATE_HANDSHAKE) && 768 (errno == EPIPE || errno == ECONNRESET)) { 769 /* 770 * Need to handle a TCP timing window where an agent continues with 771 * the sending of the next handshake or a CSM. 772 * However, the peer does not like a certificate and so sends a 773 * fatal alert and closes the TCP session. 774 * The sending of the next handshake or CSM may get terminated because 775 * of the closed TCP session, but there is still an outstanding alert 776 * to be read in and reported on. 777 * In this case, pretend that sending the info was fine so that the 778 * alert can be read (which effectively is what happens with DTLS). 779 */ 780 ret = inl; 781 } 782 } 783 } 784 return ret; 785} 786 787static int 788coap_sock_puts(BIO *a, const char *pstr) { 789 return coap_sock_write(a, pstr, (int)strlen(pstr)); 790} 791 792static long 793coap_sock_ctrl(BIO *a, int cmd, long num, void *ptr) { 794 int r = 1; 795 (void)a; 796 (void)ptr; 797 (void)num; 798 799 switch (cmd) { 800 case BIO_C_SET_FD: 801 case BIO_C_GET_FD: 802 r = -1; 803 break; 804 case BIO_CTRL_SET_CLOSE: 805 case BIO_CTRL_DUP: 806 case BIO_CTRL_FLUSH: 807 r = 1; 808 break; 809 default: 810 case BIO_CTRL_GET_CLOSE: 811 r = 0; 812 break; 813 } 814 return r; 815} 816#endif /* !COAP_DISABLE_TCP */ 817 818static void 819coap_set_user_prefs(SSL_CTX *ctx) { 820 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS); 821 822#ifdef COAP_OPENSSL_SIGALGS 823 SSL_CTX_set1_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS); 824 SSL_CTX_set1_client_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS); 825#endif 826 827#if OPENSSL_VERSION_NUMBER >= 0x10101000L && defined(COAP_OPENSSL_GROUPS) 828 SSL_CTX_set1_groups_list(ctx, COAP_OPENSSL_GROUPS); 829#endif 830} 831 832void * 833coap_dtls_new_context(coap_context_t *coap_context) { 834 coap_openssl_context_t *context; 835 (void)coap_context; 836 837 context = (coap_openssl_context_t *)coap_malloc_type(COAP_STRING, sizeof(coap_openssl_context_t)); 838 if (context) { 839 uint8_t cookie_secret[32]; 840 841 memset(context, 0, sizeof(coap_openssl_context_t)); 842 843 /* Set up DTLS context */ 844 context->dtls.ctx = SSL_CTX_new(DTLS_method()); 845 if (!context->dtls.ctx) 846 goto error; 847 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION); 848 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls); 849 SSL_CTX_set_read_ahead(context->dtls.ctx, 1); 850 coap_set_user_prefs(context->dtls.ctx); 851 memset(cookie_secret, 0, sizeof(cookie_secret)); 852 if (!RAND_bytes(cookie_secret, (int)sizeof(cookie_secret))) { 853 coap_dtls_log(COAP_LOG_WARN, 854 "Insufficient entropy for random cookie generation"); 855 coap_prng(cookie_secret, sizeof(cookie_secret)); 856 } 857 context->dtls.cookie_hmac = HMAC_CTX_new(); 858 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (int)sizeof(cookie_secret), 859 EVP_sha256(), NULL)) 860 goto error; 861 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie); 862 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie); 863 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback); 864 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU); 865#if OPENSSL_VERSION_NUMBER >= 0x30000000L 866 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_LEGACY_SERVER_CONNECT); 867#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ 868 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM, "coapdgram"); 869 if (!context->dtls.meth) 870 goto error; 871 context->dtls.bio_addr = BIO_ADDR_new(); 872 if (!context->dtls.bio_addr) 873 goto error; 874 BIO_meth_set_write(context->dtls.meth, coap_dgram_write); 875 BIO_meth_set_read(context->dtls.meth, coap_dgram_read); 876 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts); 877 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl); 878 BIO_meth_set_create(context->dtls.meth, coap_dgram_create); 879 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy); 880 881#if !COAP_DISABLE_TCP 882 /* Set up TLS context */ 883 context->tls.ctx = SSL_CTX_new(TLS_method()); 884 if (!context->tls.ctx) 885 goto error; 886 SSL_CTX_set_app_data(context->tls.ctx, &context->tls); 887 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION); 888 coap_set_user_prefs(context->tls.ctx); 889 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback); 890 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET, "coapsock"); 891 if (!context->tls.meth) 892 goto error; 893 BIO_meth_set_write(context->tls.meth, coap_sock_write); 894 BIO_meth_set_read(context->tls.meth, coap_sock_read); 895 BIO_meth_set_puts(context->tls.meth, coap_sock_puts); 896 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl); 897 BIO_meth_set_create(context->tls.meth, coap_sock_create); 898 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy); 899#endif /* !COAP_DISABLE_TCP */ 900 } 901 902 return context; 903 904error: 905 coap_dtls_free_context(context); 906 return NULL; 907} 908 909#if COAP_SERVER_SUPPORT 910int 911coap_dtls_context_set_spsk(coap_context_t *c_context, 912 coap_dtls_spsk_t *setup_data 913 ) { 914 coap_openssl_context_t *o_context = 915 ((coap_openssl_context_t *)c_context->dtls_context); 916 BIO *bio; 917 918 if (!setup_data || !o_context) 919 return 0; 920 921 SSL_CTX_set_psk_server_callback(o_context->dtls.ctx, 922 coap_dtls_psk_server_callback); 923#if !COAP_DISABLE_TCP 924 SSL_CTX_set_psk_server_callback(o_context->tls.ctx, 925 coap_dtls_psk_server_callback); 926#endif /* !COAP_DISABLE_TCP */ 927 if (setup_data->psk_info.hint.s) { 928 char hint[COAP_DTLS_HINT_LENGTH]; 929 snprintf(hint, sizeof(hint), "%.*s", (int)setup_data->psk_info.hint.length, 930 setup_data->psk_info.hint.s); 931 SSL_CTX_use_psk_identity_hint(o_context->dtls.ctx, hint); 932#if !COAP_DISABLE_TCP 933 SSL_CTX_use_psk_identity_hint(o_context->tls.ctx, hint); 934#endif /* !COAP_DISABLE_TCP */ 935 } 936 if (setup_data->validate_sni_call_back) { 937#if OPENSSL_VERSION_NUMBER < 0x10101000L 938 SSL_CTX_set_tlsext_servername_arg(o_context->dtls.ctx, 939 &c_context->spsk_setup_data); 940 SSL_CTX_set_tlsext_servername_callback(o_context->dtls.ctx, 941 psk_tls_server_name_call_back); 942#if !COAP_DISABLE_TCP 943 SSL_CTX_set_tlsext_servername_arg(o_context->tls.ctx, 944 &c_context->spsk_setup_data); 945 SSL_CTX_set_tlsext_servername_callback(o_context->tls.ctx, 946 psk_tls_server_name_call_back); 947#endif /* !COAP_DISABLE_TCP */ 948#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 949 SSL_CTX_set_client_hello_cb(o_context->dtls.ctx, 950 psk_tls_client_hello_call_back, 951 NULL); 952#if !COAP_DISABLE_TCP 953 SSL_CTX_set_client_hello_cb(o_context->tls.ctx, 954 psk_tls_client_hello_call_back, 955 NULL); 956#endif /* !COAP_DISABLE_TCP */ 957#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 958 } 959 960 if (!o_context->dtls.ssl) { 961 /* This is set up to handle new incoming sessions to a server */ 962 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx); 963 if (!o_context->dtls.ssl) 964 return 0; 965 bio = BIO_new(o_context->dtls.meth); 966 if (!bio) { 967 SSL_free(o_context->dtls.ssl); 968 o_context->dtls.ssl = NULL; 969 return 0; 970 } 971 SSL_set_bio(o_context->dtls.ssl, bio, bio); 972 SSL_set_app_data(o_context->dtls.ssl, NULL); 973 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE); 974 SSL_set_mtu(o_context->dtls.ssl, COAP_DEFAULT_MTU); 975 } 976 o_context->psk_pki_enabled |= IS_PSK; 977 return 1; 978} 979#endif /* COAP_SERVER_SUPPORT */ 980 981#if COAP_CLIENT_SUPPORT 982int 983coap_dtls_context_set_cpsk(coap_context_t *c_context, 984 coap_dtls_cpsk_t *setup_data 985 ) { 986 coap_openssl_context_t *o_context = 987 ((coap_openssl_context_t *)c_context->dtls_context); 988 BIO *bio; 989 990 if (!setup_data || !o_context) 991 return 0; 992 993 if (!o_context->dtls.ssl) { 994 /* This is set up to handle new incoming sessions to a server */ 995 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx); 996 if (!o_context->dtls.ssl) 997 return 0; 998 bio = BIO_new(o_context->dtls.meth); 999 if (!bio) { 1000 SSL_free(o_context->dtls.ssl); 1001 o_context->dtls.ssl = NULL; 1002 return 0; 1003 } 1004 SSL_set_bio(o_context->dtls.ssl, bio, bio); 1005 SSL_set_app_data(o_context->dtls.ssl, NULL); 1006 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE); 1007 SSL_set_mtu(o_context->dtls.ssl, COAP_DEFAULT_MTU); 1008 } 1009 o_context->psk_pki_enabled |= IS_PSK; 1010 return 1; 1011} 1012#endif /* COAP_CLIENT_SUPPORT */ 1013 1014static int 1015map_key_type(int asn1_private_key_type 1016 ) { 1017 switch (asn1_private_key_type) { 1018 case COAP_ASN1_PKEY_NONE: 1019 return EVP_PKEY_NONE; 1020 case COAP_ASN1_PKEY_RSA: 1021 return EVP_PKEY_RSA; 1022 case COAP_ASN1_PKEY_RSA2: 1023 return EVP_PKEY_RSA2; 1024 case COAP_ASN1_PKEY_DSA: 1025 return EVP_PKEY_DSA; 1026 case COAP_ASN1_PKEY_DSA1: 1027 return EVP_PKEY_DSA1; 1028 case COAP_ASN1_PKEY_DSA2: 1029 return EVP_PKEY_DSA2; 1030 case COAP_ASN1_PKEY_DSA3: 1031 return EVP_PKEY_DSA3; 1032 case COAP_ASN1_PKEY_DSA4: 1033 return EVP_PKEY_DSA4; 1034 case COAP_ASN1_PKEY_DH: 1035 return EVP_PKEY_DH; 1036 case COAP_ASN1_PKEY_DHX: 1037 return EVP_PKEY_DHX; 1038 case COAP_ASN1_PKEY_EC: 1039 return EVP_PKEY_EC; 1040 case COAP_ASN1_PKEY_HMAC: 1041 return EVP_PKEY_HMAC; 1042 case COAP_ASN1_PKEY_CMAC: 1043 return EVP_PKEY_CMAC; 1044 case COAP_ASN1_PKEY_TLS1_PRF: 1045 return EVP_PKEY_TLS1_PRF; 1046 case COAP_ASN1_PKEY_HKDF: 1047 return EVP_PKEY_HKDF; 1048 default: 1049 coap_log_warn("*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n", 1050 asn1_private_key_type); 1051 break; 1052 } 1053 return 0; 1054} 1055#if !COAP_DISABLE_TCP 1056static uint8_t coap_alpn[] = { 4, 'c', 'o', 'a', 'p' }; 1057 1058#if COAP_SERVER_SUPPORT 1059static int 1060server_alpn_callback(SSL *ssl COAP_UNUSED, 1061 const unsigned char **out, 1062 unsigned char *outlen, 1063 const unsigned char *in, 1064 unsigned int inlen, 1065 void *arg COAP_UNUSED 1066 ) { 1067 unsigned char *tout = NULL; 1068 int ret; 1069 if (inlen == 0) 1070 return SSL_TLSEXT_ERR_NOACK; 1071 ret = SSL_select_next_proto(&tout, 1072 outlen, 1073 coap_alpn, 1074 sizeof(coap_alpn), 1075 in, 1076 inlen); 1077 *out = tout; 1078 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK; 1079} 1080#endif /* COAP_SERVER_SUPPORT */ 1081#endif /* !COAP_DISABLE_TCP */ 1082 1083static void 1084add_ca_to_cert_store(X509_STORE *st, X509 *x509) { 1085 long e; 1086 1087 /* Flush out existing errors */ 1088 while ((e = ERR_get_error()) != 0) { 1089 } 1090 1091 if (!X509_STORE_add_cert(st, x509)) { 1092 while ((e = ERR_get_error()) != 0) { 1093 int r = ERR_GET_REASON(e); 1094 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) { 1095 /* Not already added */ 1096 coap_log_warn("***setup_pki: (D)TLS: %s%s\n", 1097 ERR_reason_error_string(e), 1098 ssl_function_definition(e)); 1099 } 1100 } 1101 } 1102} 1103 1104static X509 * 1105missing_ENGINE_load_cert(const char *cert_id) { 1106 struct { 1107 const char *cert_id; 1108 X509 *cert; 1109 } params; 1110 1111 params.cert_id = cert_id; 1112 params.cert = NULL; 1113 1114 /* There is no ENGINE_load_cert() */ 1115 if (!ENGINE_ctrl_cmd(ssl_engine, "LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) { 1116 params.cert = NULL; 1117 } 1118 return params.cert; 1119} 1120 1121#if OPENSSL_VERSION_NUMBER < 0x10101000L && COAP_SERVER_SUPPORT 1122static int 1123setup_pki_server(SSL_CTX *ctx, 1124 const coap_dtls_pki_t *setup_data 1125 ) { 1126 switch (setup_data->pki_key.key_type) { 1127 case COAP_PKI_KEY_PEM: 1128 if (setup_data->pki_key.key.pem.public_cert && 1129 setup_data->pki_key.key.pem.public_cert[0]) { 1130 if (!(SSL_CTX_use_certificate_file(ctx, 1131 setup_data->pki_key.key.pem.public_cert, 1132 SSL_FILETYPE_PEM))) { 1133 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1134 "Server Certificate\n", 1135 setup_data->pki_key.key.pem.public_cert); 1136 return 0; 1137 } 1138 } else { 1139 coap_log_err("*** setup_pki: (D)TLS: No Server Certificate defined\n"); 1140 return 0; 1141 } 1142 1143 if (setup_data->pki_key.key.pem.private_key && 1144 setup_data->pki_key.key.pem.private_key[0]) { 1145 if (!(SSL_CTX_use_PrivateKey_file(ctx, 1146 setup_data->pki_key.key.pem.private_key, 1147 SSL_FILETYPE_PEM))) { 1148 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1149 "Server Private Key\n", 1150 setup_data->pki_key.key.pem.private_key); 1151 return 0; 1152 } 1153 } else { 1154 coap_log_err("*** setup_pki: (D)TLS: No Server Private Key defined\n"); 1155 return 0; 1156 } 1157 1158 if (setup_data->check_common_ca && setup_data->pki_key.key.pem.ca_file && 1159 setup_data->pki_key.key.pem.ca_file[0]) { 1160 STACK_OF(X509_NAME) *cert_names; 1161 X509_STORE *st; 1162 BIO *in; 1163 X509 *x = NULL; 1164 char *rw_var = NULL; 1165 cert_names = SSL_load_client_CA_file(setup_data->pki_key.key.pem.ca_file); 1166 if (cert_names != NULL) 1167 SSL_CTX_set_client_CA_list(ctx, cert_names); 1168 else { 1169 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1170 "client CA File\n", 1171 setup_data->pki_key.key.pem.ca_file); 1172 return 0; 1173 } 1174 1175 /* Add CA to the trusted root CA store */ 1176 st = SSL_CTX_get_cert_store(ctx); 1177 in = BIO_new(BIO_s_file()); 1178 /* Need to do this to not get a compiler warning about const parameters */ 1179 memcpy(&rw_var, &setup_data->pki_key.key.pem.ca_file, sizeof(rw_var)); 1180 if (!BIO_read_filename(in, rw_var)) { 1181 BIO_free(in); 1182 X509_free(x); 1183 break; 1184 } 1185 1186 for (;;) { 1187 if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL) 1188 break; 1189 add_ca_to_cert_store(st, x); 1190 X509_free(x); 1191 } 1192 BIO_free(in); 1193 } 1194 break; 1195 1196 case COAP_PKI_KEY_PEM_BUF: 1197 if (setup_data->pki_key.key.pem_buf.public_cert && 1198 setup_data->pki_key.key.pem_buf.public_cert_len) { 1199 BIO *bp = BIO_new_mem_buf(setup_data->pki_key.key.pem_buf.public_cert, 1200 setup_data->pki_key.key.pem_buf.public_cert_len); 1201 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL; 1202 1203 if (!cert || !SSL_CTX_use_certificate(ctx, cert)) { 1204 coap_log_warn("*** setup_pki: (D)TLS: Unable to configure " 1205 "Server PEM Certificate\n"); 1206 if (bp) 1207 BIO_free(bp); 1208 if (cert) 1209 X509_free(cert); 1210 return 0; 1211 } 1212 if (bp) 1213 BIO_free(bp); 1214 if (cert) 1215 X509_free(cert); 1216 } else { 1217 coap_log_err("*** setup_pki: (D)TLS: No Server Certificate defined\n"); 1218 return 0; 1219 } 1220 1221 if (setup_data->pki_key.key.pem_buf.private_key && 1222 setup_data->pki_key.key.pem_buf.private_key_len) { 1223 BIO *bp = BIO_new_mem_buf(setup_data->pki_key.key.pem_buf.private_key, 1224 setup_data->pki_key.key.pem_buf.private_key_len); 1225 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL; 1226 1227 if (!pkey || !SSL_CTX_use_PrivateKey(ctx, pkey)) { 1228 coap_log_warn("*** setup_pki: (D)TLS: Unable to configure " 1229 "Server PEM Private Key\n"); 1230 if (bp) 1231 BIO_free(bp); 1232 if (pkey) 1233 EVP_PKEY_free(pkey); 1234 return 0; 1235 } 1236 if (bp) 1237 BIO_free(bp); 1238 if (pkey) 1239 EVP_PKEY_free(pkey); 1240 } else { 1241 coap_log_err("*** setup_pki: (D)TLS: No Server Private Key defined\n"); 1242 return 0; 1243 } 1244 1245 if (setup_data->pki_key.key.pem_buf.ca_cert && 1246 setup_data->pki_key.key.pem_buf.ca_cert_len) { 1247 BIO *bp = BIO_new_mem_buf(setup_data->pki_key.key.pem_buf.ca_cert, 1248 setup_data->pki_key.key.pem_buf.ca_cert_len); 1249 X509_STORE *st; 1250 X509 *x; 1251 1252 st = SSL_CTX_get_cert_store(ctx); 1253 if (bp) { 1254 for (;;) { 1255 if ((x = PEM_read_bio_X509(bp, NULL, NULL, NULL)) == NULL) 1256 break; 1257 add_ca_to_cert_store(st, x); 1258 SSL_CTX_add_client_CA(ctx, x); 1259 X509_free(x); 1260 } 1261 BIO_free(bp); 1262 } 1263 } 1264 break; 1265 1266 case COAP_PKI_KEY_ASN1: 1267 if (setup_data->pki_key.key.asn1.public_cert && 1268 setup_data->pki_key.key.asn1.public_cert_len > 0) { 1269 if (!(SSL_CTX_use_certificate_ASN1(ctx, 1270 setup_data->pki_key.key.asn1.public_cert_len, 1271 setup_data->pki_key.key.asn1.public_cert))) { 1272 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1273 "Server Certificate\n", 1274 "ASN1"); 1275 return 0; 1276 } 1277 } else { 1278 coap_log_err("*** setup_pki: (D)TLS: No Server Certificate defined\n"); 1279 return 0; 1280 } 1281 1282 if (setup_data->pki_key.key.asn1.private_key && 1283 setup_data->pki_key.key.asn1.private_key_len > 0) { 1284 int pkey_type = map_key_type(setup_data->pki_key.key.asn1.private_key_type); 1285 if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx, 1286 setup_data->pki_key.key.asn1.private_key, 1287 setup_data->pki_key.key.asn1.private_key_len))) { 1288 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1289 "Server Private Key\n", 1290 "ASN1"); 1291 return 0; 1292 } 1293 } else { 1294 coap_log_err("*** setup_pki: (D)TLS: No Server Private Key defined\n"); 1295 return 0; 1296 } 1297 1298 if (setup_data->pki_key.key.asn1.ca_cert && 1299 setup_data->pki_key.key.asn1.ca_cert_len > 0) { 1300 /* Need to use a temp variable as it gets incremented*/ 1301 const uint8_t *p = setup_data->pki_key.key.asn1.ca_cert; 1302 X509 *x509 = d2i_X509(NULL, &p, setup_data->pki_key.key.asn1.ca_cert_len); 1303 X509_STORE *st; 1304 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) { 1305 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1306 "client CA File\n", 1307 "ASN1"); 1308 if (x509) 1309 X509_free(x509); 1310 return 0; 1311 } 1312 st = SSL_CTX_get_cert_store(ctx); 1313 add_ca_to_cert_store(st, x509); 1314 X509_free(x509); 1315 } 1316 break; 1317 1318 case COAP_PKI_KEY_PKCS11: 1319 if (!ssl_engine) { 1320 ssl_engine = ENGINE_by_id("pkcs11"); 1321 if (!ssl_engine) { 1322 coap_log_err("*** setup_pki: (D)TLS: No PKCS11 support\nn"); 1323 return 0; 1324 } 1325 if (!ENGINE_init(ssl_engine)) { 1326 /* the engine couldn't initialise, release 'ssl_engine' */ 1327 ENGINE_free(ssl_engine); 1328 ssl_engine = NULL; 1329 coap_log_err("*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n"); 1330 return 0; 1331 } 1332 } 1333 1334 if (setup_data->pki_key.key.pkcs11.user_pin) { 1335 /* If not set, pin may be held in pkcs11: URI */ 1336 if (ENGINE_ctrl_cmd_string(ssl_engine, "PIN", 1337 setup_data->pki_key.key.pkcs11.user_pin, 0) == 0) { 1338 coap_log_warn("*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n", 1339 setup_data->pki_key.key.pkcs11.user_pin); 1340 return 0; 1341 } 1342 } 1343 1344 if (setup_data->pki_key.key.pkcs11.private_key && 1345 setup_data->pki_key.key.pkcs11.private_key[0]) { 1346 if (strncasecmp(setup_data->pki_key.key.pkcs11.private_key, 1347 "pkcs11:", 7) == 0) { 1348 EVP_PKEY *pkey = ENGINE_load_private_key(ssl_engine, 1349 setup_data->pki_key.key.pkcs11.private_key, 1350 NULL, NULL); 1351 1352 if (!pkey) { 1353 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load " 1354 "Server Private Key\n", 1355 setup_data->pki_key.key.pkcs11.private_key); 1356 return 0; 1357 } 1358 if (!SSL_CTX_use_PrivateKey(ctx, pkey)) { 1359 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1360 "Server Private Key\n", 1361 setup_data->pki_key.key.pkcs11.private_key); 1362 EVP_PKEY_free(pkey); 1363 return 0; 1364 } 1365 EVP_PKEY_free(pkey); 1366 } else { 1367 if (!(SSL_CTX_use_PrivateKey_file(ctx, 1368 setup_data->pki_key.key.pkcs11.private_key, 1369 SSL_FILETYPE_ASN1))) { 1370 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1371 "Server Private Key\n", 1372 setup_data->pki_key.key.pkcs11.private_key); 1373 return 0; 1374 } 1375 } 1376 } else { 1377 coap_log_err("*** setup_pki: (D)TLS: No Server Private Key defined\n"); 1378 return 0; 1379 } 1380 1381 if (setup_data->pki_key.key.pkcs11.public_cert && 1382 setup_data->pki_key.key.pkcs11.public_cert[0]) { 1383 if (strncasecmp(setup_data->pki_key.key.pkcs11.public_cert, 1384 "pkcs11:", 7) == 0) { 1385 X509 *x509; 1386 1387 x509 = missing_ENGINE_load_cert( 1388 setup_data->pki_key.key.pkcs11.public_cert); 1389 if (!x509) { 1390 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load " 1391 "Server Certificate\n", 1392 setup_data->pki_key.key.pkcs11.public_cert); 1393 return 0; 1394 } 1395 if (!SSL_CTX_use_certificate(ctx, x509)) { 1396 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1397 "Server Certificate\n", 1398 setup_data->pki_key.key.pkcs11.public_cert); 1399 X509_free(x509); 1400 return 0; 1401 } 1402 X509_free(x509); 1403 } else { 1404 if (!(SSL_CTX_use_certificate_file(ctx, 1405 setup_data->pki_key.key.pkcs11.public_cert, 1406 SSL_FILETYPE_ASN1))) { 1407 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1408 "Server Certificate\n", 1409 setup_data->pki_key.key.pkcs11.public_cert); 1410 return 0; 1411 } 1412 } 1413 } else { 1414 coap_log_err("*** setup_pki: (D)TLS: No Server Certificate defined\n"); 1415 return 0; 1416 } 1417 1418 if (setup_data->pki_key.key.pkcs11.ca && 1419 setup_data->pki_key.key.pkcs11.ca[0]) { 1420 X509_STORE *st; 1421 1422 if (strncasecmp(setup_data->pki_key.key.pkcs11.ca, "pkcs11:", 7) == 0) { 1423 X509 *x509; 1424 1425 x509 = missing_ENGINE_load_cert( 1426 setup_data->pki_key.key.pkcs11.ca); 1427 if (!x509) { 1428 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load " 1429 "Server CA Certificate\n", 1430 setup_data->pki_key.key.pkcs11.ca); 1431 return 0; 1432 } 1433 if (!SSL_CTX_add_client_CA(ctx, x509)) { 1434 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1435 "Server CA File\n", 1436 setup_data->pki_key.key.pkcs11.ca); 1437 X509_free(x509); 1438 return 0; 1439 } 1440 st = SSL_CTX_get_cert_store(ctx); 1441 add_ca_to_cert_store(st, x509); 1442 X509_free(x509); 1443 } else { 1444 FILE *fp = fopen(setup_data->pki_key.key.pkcs11.ca, "r"); 1445 X509 *x509 = fp ? d2i_X509_fp(fp, NULL) : NULL; 1446 1447 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) { 1448 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1449 "client CA File\n", 1450 setup_data->pki_key.key.pkcs11.ca); 1451 if (x509) 1452 X509_free(x509); 1453 return 0; 1454 } 1455 st = SSL_CTX_get_cert_store(ctx); 1456 add_ca_to_cert_store(st, x509); 1457 X509_free(x509); 1458 } 1459 } 1460 break; 1461 1462 default: 1463 coap_log_err("*** setup_pki: (D)TLS: Unknown key type %d\n", 1464 setup_data->pki_key.key_type); 1465 return 0; 1466 } 1467 1468 return 1; 1469} 1470#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ 1471 1472#if OPENSSL_VERSION_NUMBER >= 0x10101000L || COAP_CLIENT_SUPPORT 1473static int 1474setup_pki_ssl(SSL *ssl, 1475 coap_dtls_pki_t *setup_data, coap_dtls_role_t role 1476 ) { 1477 if (setup_data->is_rpk_not_cert) { 1478 coap_log_err("RPK Support not available in OpenSSL\n"); 1479 return 0; 1480 } 1481 switch (setup_data->pki_key.key_type) { 1482 case COAP_PKI_KEY_PEM: 1483 if (setup_data->pki_key.key.pem.public_cert && 1484 setup_data->pki_key.key.pem.public_cert[0]) { 1485 if (!(SSL_use_certificate_file(ssl, 1486 setup_data->pki_key.key.pem.public_cert, 1487 SSL_FILETYPE_PEM))) { 1488 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1489 "%s Certificate\n", 1490 setup_data->pki_key.key.pem.public_cert, 1491 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1492 return 0; 1493 } 1494 } else if (role == COAP_DTLS_ROLE_SERVER || 1495 (setup_data->pki_key.key.pem.private_key && 1496 setup_data->pki_key.key.pem.private_key[0])) { 1497 coap_log_err("*** setup_pki: (D)TLS: No %s Certificate defined\n", 1498 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1499 return 0; 1500 } 1501 if (setup_data->pki_key.key.pem.private_key && 1502 setup_data->pki_key.key.pem.private_key[0]) { 1503 if (!(SSL_use_PrivateKey_file(ssl, 1504 setup_data->pki_key.key.pem.private_key, 1505 SSL_FILETYPE_PEM))) { 1506 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1507 "Client Private Key\n", 1508 setup_data->pki_key.key.pem.private_key); 1509 return 0; 1510 } 1511 } else if (role == COAP_DTLS_ROLE_SERVER || 1512 (setup_data->pki_key.key.pem.public_cert && 1513 setup_data->pki_key.key.pem.public_cert[0])) { 1514 coap_log_err("*** setup_pki: (D)TLS: No %s Private Key defined\n", 1515 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1516 return 0; 1517 } 1518 if (setup_data->check_common_ca && setup_data->pki_key.key.pem.ca_file && 1519 setup_data->pki_key.key.pem.ca_file[0]) { 1520 X509_STORE *st; 1521 BIO *in; 1522 X509 *x = NULL; 1523 char *rw_var = NULL; 1524 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); 1525 1526 if (role == COAP_DTLS_ROLE_SERVER) { 1527 STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(setup_data->pki_key.key.pem.ca_file); 1528 1529 if (cert_names != NULL) 1530 SSL_set_client_CA_list(ssl, cert_names); 1531 else { 1532 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1533 "%s CA File\n", 1534 setup_data->pki_key.key.pem.ca_file, 1535 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1536 return 0; 1537 } 1538 } 1539 1540 /* Add CA to the trusted root CA store */ 1541 in = BIO_new(BIO_s_file()); 1542 /* Need to do this to not get a compiler warning about const parameters */ 1543 memcpy(&rw_var, &setup_data->pki_key.key.pem.ca_file, sizeof(rw_var)); 1544 if (!BIO_read_filename(in, rw_var)) { 1545 BIO_free(in); 1546 break; 1547 } 1548 st = SSL_CTX_get_cert_store(ctx); 1549 for (;;) { 1550 if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL) 1551 break; 1552 add_ca_to_cert_store(st, x); 1553 X509_free(x); 1554 } 1555 BIO_free(in); 1556 } 1557 break; 1558 1559 case COAP_PKI_KEY_PEM_BUF: 1560 if (setup_data->pki_key.key.pem_buf.public_cert && 1561 setup_data->pki_key.key.pem_buf.public_cert_len) { 1562 BIO *bp = BIO_new_mem_buf(setup_data->pki_key.key.pem_buf.public_cert, 1563 (int)setup_data->pki_key.key.pem_buf.public_cert_len); 1564 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL; 1565 1566 if (!cert || !SSL_use_certificate(ssl, cert)) { 1567 coap_log_warn("*** setup_pki: (D)TLS: Unable to configure " 1568 "Server PEM Certificate\n"); 1569 if (bp) 1570 BIO_free(bp); 1571 if (cert) 1572 X509_free(cert); 1573 return 0; 1574 } 1575 if (bp) 1576 BIO_free(bp); 1577 if (cert) 1578 X509_free(cert); 1579 } else { 1580 coap_log_err("*** setup_pki: (D)TLS: No Server Certificate defined\n"); 1581 return 0; 1582 } 1583 1584 if (setup_data->pki_key.key.pem_buf.private_key && 1585 setup_data->pki_key.key.pem_buf.private_key_len) { 1586 BIO *bp = BIO_new_mem_buf(setup_data->pki_key.key.pem_buf.private_key, 1587 (int)setup_data->pki_key.key.pem_buf.private_key_len); 1588 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL; 1589 1590 if (!pkey || !SSL_use_PrivateKey(ssl, pkey)) { 1591 coap_log_warn("*** setup_pki: (D)TLS: Unable to configure " 1592 "Server PEM Private Key\n"); 1593 if (bp) 1594 BIO_free(bp); 1595 if (pkey) 1596 EVP_PKEY_free(pkey); 1597 return 0; 1598 } 1599 if (bp) 1600 BIO_free(bp); 1601 if (pkey) 1602 EVP_PKEY_free(pkey); 1603 } else { 1604 coap_log_err("*** setup_pki: (D)TLS: No Server Private Key defined\n"); 1605 return 0; 1606 } 1607 1608 if (setup_data->pki_key.key.pem_buf.ca_cert && 1609 setup_data->pki_key.key.pem_buf.ca_cert_len) { 1610 BIO *bp = BIO_new_mem_buf(setup_data->pki_key.key.pem_buf.ca_cert, 1611 (int)setup_data->pki_key.key.pem_buf.ca_cert_len); 1612 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); 1613 X509 *x; 1614 X509_STORE *st = SSL_CTX_get_cert_store(ctx); 1615 1616 if (bp) { 1617 for (;;) { 1618 if ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)) == NULL) 1619 break; 1620 add_ca_to_cert_store(st, x); 1621 SSL_add_client_CA(ssl, x); 1622 X509_free(x); 1623 } 1624 BIO_free(bp); 1625 } 1626 } 1627 break; 1628 1629 case COAP_PKI_KEY_ASN1: 1630 if (setup_data->pki_key.key.asn1.public_cert && 1631 setup_data->pki_key.key.asn1.public_cert_len > 0) { 1632 if (!(SSL_use_certificate_ASN1(ssl, 1633 setup_data->pki_key.key.asn1.public_cert, 1634 (int)setup_data->pki_key.key.asn1.public_cert_len))) { 1635 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1636 "%s Certificate\n", 1637 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client", 1638 "ASN1"); 1639 return 0; 1640 } 1641 } else if (role == COAP_DTLS_ROLE_SERVER || 1642 (setup_data->pki_key.key.asn1.private_key && 1643 setup_data->pki_key.key.asn1.private_key[0])) { 1644 coap_log_err("*** setup_pki: (D)TLS: No %s Certificate defined\n", 1645 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1646 return 0; 1647 } 1648 if (setup_data->pki_key.key.asn1.private_key && 1649 setup_data->pki_key.key.asn1.private_key_len > 0) { 1650 int pkey_type = map_key_type(setup_data->pki_key.key.asn1.private_key_type); 1651 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl, 1652 setup_data->pki_key.key.asn1.private_key, 1653 (long)setup_data->pki_key.key.asn1.private_key_len))) { 1654 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1655 "%s Private Key\n", 1656 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client", 1657 "ASN1"); 1658 return 0; 1659 } 1660 } else if (role == COAP_DTLS_ROLE_SERVER || 1661 (setup_data->pki_key.key.asn1.public_cert && 1662 setup_data->pki_key.key.asn1.public_cert_len > 0)) { 1663 coap_log_err("*** setup_pki: (D)TLS: No %s Private Key defined", 1664 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1665 return 0; 1666 } 1667 if (setup_data->pki_key.key.asn1.ca_cert && 1668 setup_data->pki_key.key.asn1.ca_cert_len > 0) { 1669 /* Need to use a temp variable as it gets incremented*/ 1670 const uint8_t *p = setup_data->pki_key.key.asn1.ca_cert; 1671 X509 *x509 = d2i_X509(NULL, &p, (long)setup_data->pki_key.key.asn1.ca_cert_len); 1672 X509_STORE *st; 1673 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); 1674 1675 if (role == COAP_DTLS_ROLE_SERVER) { 1676 if (!x509 || !SSL_add_client_CA(ssl, x509)) { 1677 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1678 "client CA File\n", 1679 "ASN1"); 1680 X509_free(x509); 1681 return 0; 1682 } 1683 } 1684 1685 /* Add CA to the trusted root CA store */ 1686 st = SSL_CTX_get_cert_store(ctx); 1687 add_ca_to_cert_store(st, x509); 1688 X509_free(x509); 1689 } 1690 break; 1691 1692 case COAP_PKI_KEY_PKCS11: 1693 if (!ssl_engine) { 1694 ssl_engine = ENGINE_by_id("pkcs11"); 1695 if (!ssl_engine) { 1696 coap_log_err("*** setup_pki: (D)TLS: No PKCS11 support - need OpenSSL pkcs11 engine\n"); 1697 return 0; 1698 } 1699 if (!ENGINE_init(ssl_engine)) { 1700 /* the engine couldn't initialise, release 'ssl_engine' */ 1701 ENGINE_free(ssl_engine); 1702 ssl_engine = NULL; 1703 coap_log_err("*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n"); 1704 return 0; 1705 } 1706 } 1707 1708 if (setup_data->pki_key.key.pkcs11.user_pin) { 1709 /* If not set, pin may be held in pkcs11: URI */ 1710 if (ENGINE_ctrl_cmd_string(ssl_engine, 1711 "PIN", 1712 setup_data->pki_key.key.pkcs11.user_pin, 0) == 0) { 1713 coap_log_warn("*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n", 1714 setup_data->pki_key.key.pkcs11.user_pin); 1715 return 0; 1716 } 1717 } 1718 1719 if (setup_data->pki_key.key.pkcs11.private_key && 1720 setup_data->pki_key.key.pkcs11.private_key[0]) { 1721 if (strncasecmp(setup_data->pki_key.key.pkcs11.private_key, 1722 "pkcs11:", 7) == 0) { 1723 EVP_PKEY *pkey = ENGINE_load_private_key(ssl_engine, 1724 setup_data->pki_key.key.pkcs11.private_key, 1725 NULL, NULL); 1726 1727 if (!pkey) { 1728 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load " 1729 "%s Private Key\n", 1730 setup_data->pki_key.key.pkcs11.private_key, 1731 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1732 return 0; 1733 } 1734 if (!SSL_use_PrivateKey(ssl, pkey)) { 1735 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1736 "%s Private Key\n", 1737 setup_data->pki_key.key.pkcs11.private_key, 1738 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1739 EVP_PKEY_free(pkey); 1740 return 0; 1741 } 1742 EVP_PKEY_free(pkey); 1743 } else { 1744 if (!(SSL_use_PrivateKey_file(ssl, 1745 setup_data->pki_key.key.pkcs11.private_key, 1746 SSL_FILETYPE_ASN1))) { 1747 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1748 "%s Private Key\n", 1749 setup_data->pki_key.key.pkcs11.private_key, 1750 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1751 return 0; 1752 } 1753 } 1754 } else if (role == COAP_DTLS_ROLE_SERVER) { 1755 coap_log_err("*** setup_pki: (D)TLS: No Server Private Key defined\n"); 1756 return 0; 1757 } 1758 1759 if (setup_data->pki_key.key.pkcs11.public_cert && 1760 setup_data->pki_key.key.pkcs11.public_cert[0]) { 1761 if (strncasecmp(setup_data->pki_key.key.pkcs11.public_cert, 1762 "pkcs11:", 7) == 0) { 1763 X509 *x509; 1764 1765 x509 = missing_ENGINE_load_cert( 1766 setup_data->pki_key.key.pkcs11.public_cert); 1767 if (!x509) { 1768 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load " 1769 "%s Certificate\n", 1770 setup_data->pki_key.key.pkcs11.public_cert, 1771 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1772 return 0; 1773 } 1774 if (!SSL_use_certificate(ssl, x509)) { 1775 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1776 "%s Certificate\n", 1777 setup_data->pki_key.key.pkcs11.public_cert, 1778 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1779 X509_free(x509); 1780 return 0; 1781 } 1782 X509_free(x509); 1783 } else { 1784 if (!(SSL_use_certificate_file(ssl, 1785 setup_data->pki_key.key.pkcs11.public_cert, 1786 SSL_FILETYPE_ASN1))) { 1787 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1788 "%s Certificate\n", 1789 setup_data->pki_key.key.pkcs11.public_cert, 1790 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1791 return 0; 1792 } 1793 } 1794 } else if (role == COAP_DTLS_ROLE_SERVER) { 1795 coap_log_err("*** setup_pki: (D)TLS: No Server Certificate defined\n"); 1796 return 0; 1797 } 1798 1799 if (setup_data->pki_key.key.pkcs11.ca && 1800 setup_data->pki_key.key.pkcs11.ca[0]) { 1801 X509_STORE *st; 1802 1803 if (strncasecmp(setup_data->pki_key.key.pkcs11.ca, "pkcs11:", 7) == 0) { 1804 X509 *x509; 1805 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); 1806 1807 x509 = missing_ENGINE_load_cert( 1808 setup_data->pki_key.key.pkcs11.ca); 1809 if (!x509) { 1810 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load " 1811 "%s CA Certificate\n", 1812 setup_data->pki_key.key.pkcs11.ca, 1813 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1814 return 0; 1815 } 1816 if (!SSL_add_client_CA(ssl, x509)) { 1817 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1818 "%s CA Certificate\n", 1819 setup_data->pki_key.key.pkcs11.ca, 1820 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1821 X509_free(x509); 1822 return 0; 1823 } 1824 st = SSL_CTX_get_cert_store(ctx); 1825 add_ca_to_cert_store(st, x509); 1826 X509_free(x509); 1827 } else { 1828 FILE *fp = fopen(setup_data->pki_key.key.pkcs11.ca, "r"); 1829 X509 *x509 = fp ? d2i_X509_fp(fp, NULL) : NULL; 1830 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); 1831 1832 if (!x509 || !SSL_add_client_CA(ssl, x509)) { 1833 coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure " 1834 "%s CA File\n", 1835 setup_data->pki_key.key.pkcs11.ca, 1836 role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client"); 1837 if (x509) 1838 X509_free(x509); 1839 return 0; 1840 } 1841 st = SSL_CTX_get_cert_store(ctx); 1842 add_ca_to_cert_store(st, x509); 1843 X509_free(x509); 1844 } 1845 } 1846 break; 1847 1848 default: 1849 coap_log_err("*** setup_pki: (D)TLS: Unknown key type %d\n", 1850 setup_data->pki_key.key_type); 1851 return 0; 1852 } 1853 return 1; 1854} 1855#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L || COAP_CLIENT_SUPPORT */ 1856 1857static char * 1858get_san_or_cn_from_cert(X509 *x509) { 1859 if (x509) { 1860 char *cn; 1861 int n; 1862 STACK_OF(GENERAL_NAME) *san_list; 1863 char buffer[256]; 1864 1865 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL); 1866 if (san_list) { 1867 int san_count = sk_GENERAL_NAME_num(san_list); 1868 1869 for (n = 0; n < san_count; n++) { 1870 const GENERAL_NAME *name = sk_GENERAL_NAME_value(san_list, n); 1871 1872 if (name->type == GEN_DNS) { 1873 const char *dns_name = (const char *)ASN1_STRING_get0_data(name->d.dNSName); 1874 1875 /* Make sure that there is not an embedded NUL in the dns_name */ 1876 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen(dns_name)) 1877 continue; 1878 cn = OPENSSL_strdup(dns_name); 1879 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free); 1880 return cn; 1881 } 1882 } 1883 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free); 1884 } 1885 /* Otherwise look for the CN= field */ 1886 X509_NAME_oneline(X509_get_subject_name(x509), buffer, sizeof(buffer)); 1887 1888 /* Need to emulate strcasestr() here. Looking for CN= */ 1889 n = (int)strlen(buffer) - 3; 1890 cn = buffer; 1891 while (n > 0) { 1892 if (((cn[0] == 'C') || (cn[0] == 'c')) && 1893 ((cn[1] == 'N') || (cn[1] == 'n')) && 1894 (cn[2] == '=')) { 1895 cn += 3; 1896 break; 1897 } 1898 cn++; 1899 n--; 1900 } 1901 if (n > 0) { 1902 char *ecn = strchr(cn, '/'); 1903 if (ecn) { 1904 return OPENSSL_strndup(cn, ecn-cn); 1905 } else { 1906 return OPENSSL_strdup(cn); 1907 } 1908 } 1909 } 1910 return NULL; 1911} 1912 1913static int 1914tls_verify_call_back(int preverify_ok, X509_STORE_CTX *ctx) { 1915 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, 1916 SSL_get_ex_data_X509_STORE_CTX_idx()); 1917 coap_session_t *session = SSL_get_app_data(ssl); 1918 coap_openssl_context_t *context = 1919 ((coap_openssl_context_t *)session->context->dtls_context); 1920 coap_dtls_pki_t *setup_data = &context->setup_data; 1921 int depth = X509_STORE_CTX_get_error_depth(ctx); 1922 int err = X509_STORE_CTX_get_error(ctx); 1923 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx); 1924 char *cn = get_san_or_cn_from_cert(x509); 1925 int keep_preverify_ok = preverify_ok; 1926 1927 if (!preverify_ok) { 1928 switch (err) { 1929 case X509_V_ERR_CERT_NOT_YET_VALID: 1930 case X509_V_ERR_CERT_HAS_EXPIRED: 1931 if (setup_data->allow_expired_certs) 1932 preverify_ok = 1; 1933 break; 1934 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 1935 if (setup_data->allow_self_signed && !setup_data->check_common_ca) 1936 preverify_ok = 1; 1937 break; 1938 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: /* Set if the CA is not known */ 1939 if (!setup_data->verify_peer_cert) 1940 preverify_ok = 1; 1941 break; 1942 case X509_V_ERR_UNABLE_TO_GET_CRL: 1943 if (setup_data->allow_no_crl) 1944 preverify_ok = 1; 1945 break; 1946 case X509_V_ERR_CRL_NOT_YET_VALID: 1947 case X509_V_ERR_CRL_HAS_EXPIRED: 1948 if (setup_data->allow_expired_crl) 1949 preverify_ok = 1; 1950 break; 1951 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 1952 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: 1953 case X509_V_ERR_AKID_SKID_MISMATCH: 1954 if (!setup_data->verify_peer_cert) 1955 preverify_ok = 1; 1956 break; 1957 default: 1958 break; 1959 } 1960 if (setup_data->cert_chain_validation && 1961 depth > (setup_data->cert_chain_verify_depth + 1)) { 1962 preverify_ok = 0; 1963 err = X509_V_ERR_CERT_CHAIN_TOO_LONG; 1964 X509_STORE_CTX_set_error(ctx, err); 1965 } 1966 if (!preverify_ok) { 1967 if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) { 1968 coap_log_warn(" %s: %s: '%s' depth=%d\n", 1969 coap_session_str(session), 1970 "Unknown CA", cn ? cn : "?", depth); 1971 } else { 1972 coap_log_warn(" %s: %s: '%s' depth=%d\n", 1973 coap_session_str(session), 1974 X509_verify_cert_error_string(err), cn ? cn : "?", depth); 1975 } 1976 } else { 1977 coap_log_info(" %s: %s: overridden: '%s' depth=%d\n", 1978 coap_session_str(session), 1979 X509_verify_cert_error_string(err), cn ? cn : "?", depth); 1980 } 1981 } 1982 /* Certificate - depth == 0 is the Client Cert */ 1983 if (setup_data->validate_cn_call_back && keep_preverify_ok) { 1984 int length = i2d_X509(x509, NULL); 1985 uint8_t *base_buf; 1986 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length); 1987 1988 /* base_buf2 gets moved to the end */ 1989 i2d_X509(x509, &base_buf2); 1990 if (!setup_data->validate_cn_call_back(cn, base_buf, length, session, 1991 depth, preverify_ok, 1992 setup_data->cn_call_back_arg)) { 1993 if (depth == 0) { 1994 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); 1995 } else { 1996 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA); 1997 } 1998 preverify_ok = 0; 1999 } 2000 OPENSSL_free(base_buf); 2001 } 2002 OPENSSL_free(cn); 2003 return preverify_ok; 2004} 2005 2006#if COAP_SERVER_SUPPORT 2007#if OPENSSL_VERSION_NUMBER < 0x10101000L 2008/* 2009 * During the SSL/TLS initial negotiations, tls_secret_call_back() is called so 2010 * it is possible to determine whether this is a PKI or PSK incoming 2011 * request and adjust the ciphers if necessary 2012 * 2013 * Set up by SSL_set_session_secret_cb() in tls_server_name_call_back() 2014 */ 2015static int 2016tls_secret_call_back(SSL *ssl, 2017 void *secret, 2018 int *secretlen, 2019 STACK_OF(SSL_CIPHER) *peer_ciphers, 2020 const SSL_CIPHER **cipher COAP_UNUSED, 2021 void *arg 2022 ) { 2023 int ii; 2024 int psk_requested = 0; 2025 coap_session_t *session; 2026 coap_dtls_pki_t *setup_data = (coap_dtls_pki_t *)arg; 2027 2028 session = (coap_session_t *)SSL_get_app_data(ssl); 2029 assert(session != NULL); 2030 assert(session->context != NULL); 2031 if (session == NULL || 2032 session->context == NULL) 2033 return 0; 2034 2035 if ((session->psk_key) || 2036 (session->context->spsk_setup_data.psk_info.key.s && 2037 session->context->spsk_setup_data.psk_info.key.length)) { 2038 /* Is PSK being requested - if so, we need to change algorithms */ 2039 for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) { 2040 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii); 2041 2042 coap_dtls_log(COAP_LOG_INFO, "Client cipher: %s\n", 2043 SSL_CIPHER_get_name(peer_cipher)); 2044 if (strstr(SSL_CIPHER_get_name(peer_cipher), "PSK")) { 2045 psk_requested = 1; 2046 break; 2047 } 2048 } 2049 } 2050 if (!psk_requested) { 2051 coap_log_debug(" %s: Using PKI ciphers\n", 2052 coap_session_str(session)); 2053 2054 if (setup_data->verify_peer_cert) { 2055 SSL_set_verify(ssl, 2056 SSL_VERIFY_PEER | 2057 SSL_VERIFY_CLIENT_ONCE | 2058 SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 2059 tls_verify_call_back); 2060 } else { 2061 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back); 2062 } 2063 2064 /* Check CA Chain */ 2065 if (setup_data->cert_chain_validation) 2066 SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth + 2); 2067 2068 /* Certificate Revocation */ 2069 if (setup_data->check_cert_revocation) { 2070 X509_VERIFY_PARAM *param; 2071 2072 param = X509_VERIFY_PARAM_new(); 2073 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); 2074 SSL_set1_param(ssl, param); 2075 X509_VERIFY_PARAM_free(param); 2076 } 2077 if (setup_data->additional_tls_setup_call_back) { 2078 /* Additional application setup wanted */ 2079 if (!setup_data->additional_tls_setup_call_back(ssl, setup_data)) 2080 return 0; 2081 } 2082 } else { 2083 if (session->psk_key) { 2084 memcpy(secret, session->psk_key->s, session->psk_key->length); 2085 *secretlen = session->psk_key->length; 2086 } else if (session->context->spsk_setup_data.psk_info.key.s && 2087 session->context->spsk_setup_data.psk_info.key.length) { 2088 memcpy(secret, session->context->spsk_setup_data.psk_info.key.s, 2089 session->context->spsk_setup_data.psk_info.key.length); 2090 *secretlen = session->context->spsk_setup_data.psk_info.key.length; 2091 } 2092 coap_log_debug(" %s: Setting PSK ciphers\n", 2093 coap_session_str(session)); 2094 /* 2095 * Force a PSK algorithm to be used, so we do PSK 2096 */ 2097 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS); 2098 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback); 2099 } 2100 return 0; 2101} 2102 2103/* 2104 * During the SSL/TLS initial negotiations, tls_server_name_call_back() is 2105 * called so it is possible to set up an extra callback to determine whether 2106 * this is a PKI or PSK incoming request and adjust the ciphers if necessary 2107 * 2108 * Set up by SSL_CTX_set_tlsext_servername_callback() in 2109 * coap_dtls_context_set_pki() 2110 */ 2111static int 2112tls_server_name_call_back(SSL *ssl, 2113 int *sd COAP_UNUSED, 2114 void *arg 2115 ) { 2116 coap_dtls_pki_t *setup_data = (coap_dtls_pki_t *)arg; 2117 2118 if (!ssl) { 2119 return SSL_TLSEXT_ERR_NOACK; 2120 } 2121 2122 if (setup_data->validate_sni_call_back) { 2123 /* SNI checking requested */ 2124 coap_session_t *session = (coap_session_t *)SSL_get_app_data(ssl); 2125 coap_openssl_context_t *context = 2126 ((coap_openssl_context_t *)session->context->dtls_context); 2127 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); 2128 size_t i; 2129 2130 if (!sni || !sni[0]) { 2131 sni = ""; 2132 } 2133 for (i = 0; i < context->sni_count; i++) { 2134 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) { 2135 break; 2136 } 2137 } 2138 if (i == context->sni_count) { 2139 SSL_CTX *ctx; 2140 coap_dtls_pki_t sni_setup_data; 2141 coap_dtls_key_t *new_entry = setup_data->validate_sni_call_back(sni, 2142 setup_data->sni_call_back_arg); 2143 if (!new_entry) { 2144 return SSL_TLSEXT_ERR_ALERT_FATAL; 2145 } 2146 /* Need to set up a new SSL_CTX to switch to */ 2147 if (session->proto == COAP_PROTO_DTLS) { 2148 /* Set up DTLS context */ 2149 ctx = SSL_CTX_new(DTLS_method()); 2150 if (!ctx) 2151 goto error; 2152 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION); 2153 SSL_CTX_set_app_data(ctx, &context->dtls); 2154 SSL_CTX_set_read_ahead(ctx, 1); 2155 coap_set_user_prefs(ctx); 2156 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie); 2157 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie); 2158 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback); 2159 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU); 2160 } 2161#if !COAP_DISABLE_TCP 2162 else { 2163 /* Set up TLS context */ 2164 ctx = SSL_CTX_new(TLS_method()); 2165 if (!ctx) 2166 goto error; 2167 SSL_CTX_set_app_data(ctx, &context->tls); 2168 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); 2169 coap_set_user_prefs(ctx); 2170 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback); 2171 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL); 2172 } 2173#endif /* !COAP_DISABLE_TCP */ 2174 sni_setup_data = *setup_data; 2175 sni_setup_data.pki_key = *new_entry; 2176 setup_pki_server(ctx, &sni_setup_data); 2177 2178 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list, 2179 (context->sni_count+1)*sizeof(sni_entry)); 2180 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni); 2181 context->sni_entry_list[context->sni_count].ctx = ctx; 2182 context->sni_count++; 2183 } 2184 SSL_set_SSL_CTX(ssl, context->sni_entry_list[i].ctx); 2185 SSL_clear_options(ssl, 0xFFFFFFFFL); 2186 SSL_set_options(ssl, SSL_CTX_get_options(context->sni_entry_list[i].ctx)); 2187 } 2188 2189 /* 2190 * Have to do extra call back next to get client algorithms 2191 * SSL_get_client_ciphers() does not work this early on 2192 */ 2193 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg); 2194 return SSL_TLSEXT_ERR_OK; 2195 2196error: 2197 return SSL_TLSEXT_ERR_ALERT_WARNING; 2198} 2199 2200/* 2201 * During the SSL/TLS initial negotiations, psk_tls_server_name_call_back() is 2202 * called to see if SNI is being used. 2203 * 2204 * Set up by SSL_CTX_set_tlsext_servername_callback() 2205 * in coap_dtls_context_set_spsk() 2206 */ 2207static int 2208psk_tls_server_name_call_back(SSL *ssl, 2209 int *sd COAP_UNUSED, 2210 void *arg 2211 ) { 2212 coap_dtls_spsk_t *setup_data = (coap_dtls_spsk_t *)arg; 2213 2214 if (!ssl) { 2215 return SSL_TLSEXT_ERR_NOACK; 2216 } 2217 2218 if (setup_data->validate_sni_call_back) { 2219 /* SNI checking requested */ 2220 coap_session_t *c_session = (coap_session_t *)SSL_get_app_data(ssl); 2221 coap_openssl_context_t *o_context = 2222 ((coap_openssl_context_t *)c_session->context->dtls_context); 2223 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); 2224 size_t i; 2225 char lhint[COAP_DTLS_HINT_LENGTH]; 2226 2227 if (!sni || !sni[0]) { 2228 sni = ""; 2229 } 2230 for (i = 0; i < o_context->psk_sni_count; i++) { 2231 if (!strcasecmp(sni, (char *)o_context->psk_sni_entry_list[i].sni)) { 2232 break; 2233 } 2234 } 2235 if (i == o_context->psk_sni_count) { 2236 SSL_CTX *ctx; 2237 const coap_dtls_spsk_info_t *new_entry = 2238 setup_data->validate_sni_call_back(sni, 2239 c_session, 2240 setup_data->sni_call_back_arg); 2241 if (!new_entry) { 2242 return SSL_TLSEXT_ERR_ALERT_FATAL; 2243 } 2244 /* Need to set up a new SSL_CTX to switch to */ 2245 if (c_session->proto == COAP_PROTO_DTLS) { 2246 /* Set up DTLS context */ 2247 ctx = SSL_CTX_new(DTLS_method()); 2248 if (!ctx) 2249 goto error; 2250 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION); 2251 SSL_CTX_set_app_data(ctx, &o_context->dtls); 2252 SSL_CTX_set_read_ahead(ctx, 1); 2253 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS); 2254 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie); 2255 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie); 2256 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback); 2257 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU); 2258 } 2259#if !COAP_DISABLE_TCP 2260 else { 2261 /* Set up TLS context */ 2262 ctx = SSL_CTX_new(TLS_method()); 2263 if (!ctx) 2264 goto error; 2265 SSL_CTX_set_app_data(ctx, &o_context->tls); 2266 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); 2267 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS); 2268 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback); 2269 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL); 2270 } 2271#endif /* !COAP_DISABLE_TCP */ 2272 2273 o_context->psk_sni_entry_list = 2274 OPENSSL_realloc(o_context->psk_sni_entry_list, 2275 (o_context->psk_sni_count+1)*sizeof(psk_sni_entry)); 2276 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni = 2277 OPENSSL_strdup(sni); 2278 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info = 2279 *new_entry; 2280 o_context->psk_sni_entry_list[o_context->psk_sni_count].ctx = 2281 ctx; 2282 o_context->psk_sni_count++; 2283 } 2284 SSL_set_SSL_CTX(ssl, o_context->psk_sni_entry_list[i].ctx); 2285 SSL_clear_options(ssl, 0xFFFFFFFFL); 2286 SSL_set_options(ssl, 2287 SSL_CTX_get_options(o_context->psk_sni_entry_list[i].ctx)); 2288 coap_session_refresh_psk_key(c_session, 2289 &o_context->psk_sni_entry_list[i].psk_info.key); 2290 snprintf(lhint, sizeof(lhint), "%.*s", 2291 (int)o_context->psk_sni_entry_list[i].psk_info.hint.length, 2292 o_context->psk_sni_entry_list[i].psk_info.hint.s); 2293 SSL_use_psk_identity_hint(ssl, lhint); 2294 } 2295 2296 /* 2297 * Have to do extra call back next to get client algorithms 2298 * SSL_get_client_ciphers() does not work this early on 2299 */ 2300 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg); 2301 return SSL_TLSEXT_ERR_OK; 2302 2303error: 2304 return SSL_TLSEXT_ERR_ALERT_WARNING; 2305} 2306#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 2307/* 2308 * During the SSL/TLS initial negotiations, tls_client_hello_call_back() is 2309 * called early in the Client Hello processing so it is possible to determine 2310 * whether this is a PKI or PSK incoming request and adjust the ciphers if 2311 * necessary. 2312 * 2313 * Set up by SSL_CTX_set_client_hello_cb(). 2314 */ 2315static int 2316tls_client_hello_call_back(SSL *ssl, 2317 int *al, 2318 void *arg COAP_UNUSED 2319 ) { 2320 coap_session_t *session; 2321 coap_openssl_context_t *dtls_context; 2322 coap_dtls_pki_t *setup_data; 2323 int psk_requested = 0; 2324 const unsigned char *out; 2325 size_t outlen; 2326 2327 if (!ssl) { 2328 *al = SSL_AD_INTERNAL_ERROR; 2329 return SSL_CLIENT_HELLO_ERROR; 2330 } 2331 session = (coap_session_t *)SSL_get_app_data(ssl); 2332 assert(session != NULL); 2333 assert(session->context != NULL); 2334 assert(session->context->dtls_context != NULL); 2335 if (session == NULL || 2336 session->context == NULL || 2337 session->context->dtls_context == NULL) { 2338 *al = SSL_AD_INTERNAL_ERROR; 2339 return SSL_CLIENT_HELLO_ERROR; 2340 } 2341 dtls_context = (coap_openssl_context_t *)session->context->dtls_context; 2342 setup_data = &dtls_context->setup_data; 2343 2344 /* 2345 * See if PSK being requested 2346 */ 2347 if ((session->psk_key) || 2348 (session->context->spsk_setup_data.psk_info.key.s && 2349 session->context->spsk_setup_data.psk_info.key.length)) { 2350 size_t len = SSL_client_hello_get0_ciphers(ssl, &out); 2351 STACK_OF(SSL_CIPHER) *peer_ciphers = NULL; 2352 STACK_OF(SSL_CIPHER) *scsvc = NULL; 2353 2354 if (len && SSL_bytes_to_cipher_list(ssl, out, len, 2355 SSL_client_hello_isv2(ssl), 2356 &peer_ciphers, &scsvc)) { 2357 int ii; 2358 for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) { 2359 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii); 2360 2361 coap_dtls_log(COAP_LOG_INFO, 2362 "Client cipher: %s (%04x)\n", 2363 SSL_CIPHER_get_name(peer_cipher), 2364 SSL_CIPHER_get_protocol_id(peer_cipher)); 2365 if (strstr(SSL_CIPHER_get_name(peer_cipher), "PSK")) { 2366 psk_requested = 1; 2367 break; 2368 } 2369 } 2370 } 2371 sk_SSL_CIPHER_free(peer_ciphers); 2372 sk_SSL_CIPHER_free(scsvc); 2373 } 2374 2375 if (psk_requested) { 2376 /* 2377 * Client has requested PSK and it is supported 2378 */ 2379 coap_log_debug(" %s: PSK request\n", 2380 coap_session_str(session)); 2381 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback); 2382 if (setup_data->additional_tls_setup_call_back) { 2383 /* Additional application setup wanted */ 2384 if (!setup_data->additional_tls_setup_call_back(ssl, setup_data)) 2385 return 0; 2386 } 2387 return SSL_CLIENT_HELLO_SUCCESS; 2388 } 2389 2390 /* 2391 * Handle Certificate requests 2392 */ 2393 2394 /* 2395 * Determine what type of certificate is being requested 2396 */ 2397 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type, 2398 &out, &outlen)) { 2399 size_t ii; 2400 for (ii = 0; ii < outlen; ii++) { 2401 switch (out[ii]) { 2402 case 0: 2403 /* RFC6091 X.509 */ 2404 if (outlen >= 2) { 2405 /* X.509 cannot be the singular entry. RFC6091 3.1. Client Hello */ 2406 goto is_x509; 2407 } 2408 break; 2409 case 2: 2410 /* RFC7250 RPK - not yet supported */ 2411 break; 2412 default: 2413 break; 2414 } 2415 } 2416 *al = SSL_AD_UNSUPPORTED_EXTENSION; 2417 return SSL_CLIENT_HELLO_ERROR; 2418 } 2419 2420is_x509: 2421 if (setup_data->validate_sni_call_back) { 2422 /* 2423 * SNI checking requested 2424 */ 2425 coap_dtls_pki_t sni_setup_data; 2426 coap_openssl_context_t *context = 2427 ((coap_openssl_context_t *)session->context->dtls_context); 2428 const char *sni = ""; 2429 char *sni_tmp = NULL; 2430 size_t i; 2431 2432 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) && 2433 outlen > 5 && 2434 (((out[0]<<8) + out[1] +2) == (int)outlen) && 2435 out[2] == TLSEXT_NAMETYPE_host_name && 2436 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) { 2437 /* Skip over length, type and length */ 2438 out += 5; 2439 outlen -= 5; 2440 sni_tmp = OPENSSL_malloc(outlen+1); 2441 sni_tmp[outlen] = '\000'; 2442 memcpy(sni_tmp, out, outlen); 2443 sni = sni_tmp; 2444 } 2445 /* Is this a cached entry? */ 2446 for (i = 0; i < context->sni_count; i++) { 2447 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) { 2448 break; 2449 } 2450 } 2451 if (i == context->sni_count) { 2452 /* 2453 * New SNI request 2454 */ 2455 coap_dtls_key_t *new_entry = setup_data->validate_sni_call_back(sni, 2456 setup_data->sni_call_back_arg); 2457 if (!new_entry) { 2458 *al = SSL_AD_UNRECOGNIZED_NAME; 2459 return SSL_CLIENT_HELLO_ERROR; 2460 } 2461 2462 2463 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list, 2464 (context->sni_count+1)*sizeof(sni_entry)); 2465 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni); 2466 context->sni_entry_list[context->sni_count].pki_key = *new_entry; 2467 context->sni_count++; 2468 } 2469 if (sni_tmp) { 2470 OPENSSL_free(sni_tmp); 2471 } 2472 sni_setup_data = *setup_data; 2473 sni_setup_data.pki_key = context->sni_entry_list[i].pki_key; 2474 setup_pki_ssl(ssl, &sni_setup_data, COAP_DTLS_ROLE_SERVER); 2475 } else { 2476 setup_pki_ssl(ssl, setup_data, COAP_DTLS_ROLE_SERVER); 2477 } 2478 2479 coap_log_debug(" %s: Using PKI ciphers\n", 2480 coap_session_str(session)); 2481 2482 if (setup_data->verify_peer_cert) { 2483 SSL_set_verify(ssl, 2484 SSL_VERIFY_PEER | 2485 SSL_VERIFY_CLIENT_ONCE | 2486 SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 2487 tls_verify_call_back); 2488 } else { 2489 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back); 2490 } 2491 2492 /* Check CA Chain */ 2493 if (setup_data->cert_chain_validation) 2494 SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth + 2); 2495 2496 /* Certificate Revocation */ 2497 if (setup_data->check_cert_revocation) { 2498 X509_VERIFY_PARAM *param; 2499 2500 param = X509_VERIFY_PARAM_new(); 2501 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); 2502 SSL_set1_param(ssl, param); 2503 X509_VERIFY_PARAM_free(param); 2504 } 2505 if (setup_data->additional_tls_setup_call_back) { 2506 /* Additional application setup wanted */ 2507 if (!setup_data->additional_tls_setup_call_back(ssl, setup_data)) 2508 return 0; 2509 } 2510 return SSL_CLIENT_HELLO_SUCCESS; 2511} 2512 2513/* 2514 * During the SSL/TLS initial negotiations, psk_tls_client_hello_call_back() is 2515 * called early in the Client Hello processing so it is possible to determine 2516 * whether SNI needs to be handled 2517 * 2518 * Set up by SSL_CTX_set_client_hello_cb(). 2519 */ 2520static int 2521psk_tls_client_hello_call_back(SSL *ssl, 2522 int *al, 2523 void *arg COAP_UNUSED 2524 ) { 2525 coap_session_t *c_session; 2526 coap_openssl_context_t *o_context; 2527 coap_dtls_spsk_t *setup_data; 2528 const unsigned char *out; 2529 size_t outlen; 2530 2531 if (!ssl) 2532 goto int_err; 2533 c_session = (coap_session_t *)SSL_get_app_data(ssl); 2534 if (!c_session || !c_session->context) { 2535 goto int_err; 2536 } 2537 o_context = (coap_openssl_context_t *)c_session->context->dtls_context; 2538 if (!o_context) { 2539 goto int_err; 2540 } 2541 setup_data = &c_session->context->spsk_setup_data; 2542 2543 if (setup_data->validate_sni_call_back) { 2544 /* 2545 * SNI checking requested 2546 */ 2547 const char *sni = ""; 2548 char *sni_tmp = NULL; 2549 size_t i; 2550 char lhint[COAP_DTLS_HINT_LENGTH]; 2551 2552 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) && 2553 outlen > 5 && 2554 (((out[0]<<8) + out[1] +2) == (int)outlen) && 2555 out[2] == TLSEXT_NAMETYPE_host_name && 2556 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) { 2557 /* Skip over length, type and length */ 2558 out += 5; 2559 outlen -= 5; 2560 sni_tmp = OPENSSL_malloc(outlen+1); 2561 if (sni_tmp) { 2562 sni_tmp[outlen] = '\000'; 2563 memcpy(sni_tmp, out, outlen); 2564 sni = sni_tmp; 2565 } 2566 } 2567 2568 /* Is this a cached entry? */ 2569 for (i = 0; i < o_context->psk_sni_count; i++) { 2570 if (strcasecmp(sni, o_context->psk_sni_entry_list[i].sni) == 0) { 2571 break; 2572 } 2573 } 2574 if (i == o_context->psk_sni_count) { 2575 /* 2576 * New SNI request 2577 */ 2578 psk_sni_entry *tmp_entry; 2579 const coap_dtls_spsk_info_t *new_entry = setup_data->validate_sni_call_back( 2580 sni, 2581 c_session, 2582 setup_data->sni_call_back_arg); 2583 if (!new_entry) { 2584 *al = SSL_AD_UNRECOGNIZED_NAME; 2585 return SSL_CLIENT_HELLO_ERROR; 2586 } 2587 2588 tmp_entry = 2589 OPENSSL_realloc(o_context->psk_sni_entry_list, 2590 (o_context->psk_sni_count+1)*sizeof(sni_entry)); 2591 if (tmp_entry) { 2592 o_context->psk_sni_entry_list = tmp_entry; 2593 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni = 2594 OPENSSL_strdup(sni); 2595 if (o_context->psk_sni_entry_list[o_context->psk_sni_count].sni) { 2596 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info = 2597 *new_entry; 2598 o_context->psk_sni_count++; 2599 } 2600 } 2601 } 2602 if (sni_tmp) { 2603 OPENSSL_free(sni_tmp); 2604 } 2605 if (coap_session_refresh_psk_hint(c_session, 2606 &o_context->psk_sni_entry_list[i].psk_info.hint) 2607 == 0) { 2608 goto int_err; 2609 } 2610 if (coap_session_refresh_psk_key(c_session, 2611 &o_context->psk_sni_entry_list[i].psk_info.key) 2612 == 0) { 2613 goto int_err; 2614 } 2615 if (o_context->psk_sni_entry_list[i].psk_info.hint.s) { 2616 snprintf(lhint, sizeof(lhint), "%.*s", 2617 (int)o_context->psk_sni_entry_list[i].psk_info.hint.length, 2618 o_context->psk_sni_entry_list[i].psk_info.hint.s); 2619 SSL_use_psk_identity_hint(ssl, lhint); 2620 } 2621 } 2622 return SSL_CLIENT_HELLO_SUCCESS; 2623 2624int_err: 2625 *al = SSL_AD_INTERNAL_ERROR; 2626 return SSL_CLIENT_HELLO_ERROR; 2627} 2628#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 2629#endif /* COAP_SERVER_SUPPORT */ 2630 2631int 2632coap_dtls_context_set_pki(coap_context_t *ctx, 2633 const coap_dtls_pki_t *setup_data, 2634 const coap_dtls_role_t role 2635 ) { 2636 coap_openssl_context_t *context = 2637 ((coap_openssl_context_t *)ctx->dtls_context); 2638 BIO *bio; 2639 if (!setup_data) 2640 return 0; 2641 context->setup_data = *setup_data; 2642 if (!context->setup_data.verify_peer_cert) { 2643 /* Needs to be clear so that no CA DNs are transmitted */ 2644 context->setup_data.check_common_ca = 0; 2645 /* Allow all of these but warn if issue */ 2646 context->setup_data.allow_self_signed = 1; 2647 context->setup_data.allow_expired_certs = 1; 2648 context->setup_data.cert_chain_validation = 1; 2649 context->setup_data.cert_chain_verify_depth = 10; 2650 context->setup_data.check_cert_revocation = 1; 2651 context->setup_data.allow_no_crl = 1; 2652 context->setup_data.allow_expired_crl = 1; 2653 context->setup_data.allow_bad_md_hash = 1; 2654 context->setup_data.allow_short_rsa_length = 1; 2655 } 2656#if COAP_SERVER_SUPPORT 2657 if (role == COAP_DTLS_ROLE_SERVER) { 2658 if (context->dtls.ctx) { 2659 /* SERVER DTLS */ 2660#if OPENSSL_VERSION_NUMBER < 0x10101000L 2661 if (!setup_pki_server(context->dtls.ctx, setup_data)) 2662 return 0; 2663#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ 2664 /* libcoap is managing TLS connection based on setup_data options */ 2665 /* Need to set up logic to differentiate between a PSK or PKI session */ 2666 /* 2667 * For OpenSSL 1.1.1, we need to use SSL_CTX_set_client_hello_cb() 2668 * which is not in 1.1.0 2669 */ 2670#if OPENSSL_VERSION_NUMBER < 0x10101000L 2671 if (SSLeay() >= 0x10101000L) { 2672 coap_log_warn("OpenSSL compiled with %lux, linked with %lux, so " 2673 "no certificate checking\n", 2674 OPENSSL_VERSION_NUMBER, SSLeay()); 2675 } 2676 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data); 2677 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx, 2678 tls_server_name_call_back); 2679#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 2680 SSL_CTX_set_client_hello_cb(context->dtls.ctx, 2681 tls_client_hello_call_back, 2682 NULL); 2683#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 2684 } 2685#if !COAP_DISABLE_TCP 2686 if (context->tls.ctx) { 2687 /* SERVER TLS */ 2688#if OPENSSL_VERSION_NUMBER < 0x10101000L 2689 if (!setup_pki_server(context->tls.ctx, setup_data)) 2690 return 0; 2691#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ 2692 /* libcoap is managing TLS connection based on setup_data options */ 2693 /* Need to set up logic to differentiate between a PSK or PKI session */ 2694 /* 2695 * For OpenSSL 1.1.1, we need to use SSL_CTX_set_client_hello_cb() 2696 * which is not in 1.1.0 2697 */ 2698#if OPENSSL_VERSION_NUMBER < 0x10101000L 2699 if (SSLeay() >= 0x10101000L) { 2700 coap_log_warn("OpenSSL compiled with %lux, linked with %lux, so " 2701 "no certificate checking\n", 2702 OPENSSL_VERSION_NUMBER, SSLeay()); 2703 } 2704 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data); 2705 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx, 2706 tls_server_name_call_back); 2707#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 2708 SSL_CTX_set_client_hello_cb(context->tls.ctx, 2709 tls_client_hello_call_back, 2710 NULL); 2711#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ 2712 /* TLS Only */ 2713 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL); 2714 } 2715#endif /* !COAP_DISABLE_TCP */ 2716 } 2717#else /* ! COAP_SERVER_SUPPORT */ 2718 (void)role; 2719#endif /* ! COAP_SERVER_SUPPORT */ 2720 2721 if (!context->dtls.ssl) { 2722 /* This is set up to handle new incoming sessions to a server */ 2723 context->dtls.ssl = SSL_new(context->dtls.ctx); 2724 if (!context->dtls.ssl) 2725 return 0; 2726 bio = BIO_new(context->dtls.meth); 2727 if (!bio) { 2728 SSL_free(context->dtls.ssl); 2729 context->dtls.ssl = NULL; 2730 return 0; 2731 } 2732 SSL_set_bio(context->dtls.ssl, bio, bio); 2733 SSL_set_app_data(context->dtls.ssl, NULL); 2734 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE); 2735 SSL_set_mtu(context->dtls.ssl, COAP_DEFAULT_MTU); 2736 } 2737 context->psk_pki_enabled |= IS_PKI; 2738 return 1; 2739} 2740 2741int 2742coap_dtls_context_set_pki_root_cas(coap_context_t *ctx, 2743 const char *ca_file, 2744 const char *ca_dir 2745 ) { 2746 coap_openssl_context_t *context = 2747 ((coap_openssl_context_t *)ctx->dtls_context); 2748 if (context->dtls.ctx) { 2749 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) { 2750 coap_log_warn("Unable to install root CAs (%s/%s)\n", 2751 ca_file ? ca_file : "NULL", ca_dir ? ca_dir : "NULL"); 2752 return 0; 2753 } 2754 } 2755#if !COAP_DISABLE_TCP 2756 if (context->tls.ctx) { 2757 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) { 2758 coap_log_warn("Unable to install root CAs (%s/%s)\n", 2759 ca_file ? ca_file : "NULL", ca_dir ? ca_dir : "NULL"); 2760 return 0; 2761 } 2762 } 2763#endif /* !COAP_DISABLE_TCP */ 2764 return 1; 2765} 2766 2767int 2768coap_dtls_context_check_keys_enabled(coap_context_t *ctx) { 2769 coap_openssl_context_t *context = 2770 ((coap_openssl_context_t *)ctx->dtls_context); 2771 return context->psk_pki_enabled ? 1 : 0; 2772} 2773 2774 2775void 2776coap_dtls_free_context(void *handle) { 2777 size_t i; 2778 coap_openssl_context_t *context = (coap_openssl_context_t *)handle; 2779 2780 if (context->dtls.ssl) 2781 SSL_free(context->dtls.ssl); 2782 if (context->dtls.ctx) 2783 SSL_CTX_free(context->dtls.ctx); 2784 if (context->dtls.cookie_hmac) 2785 HMAC_CTX_free(context->dtls.cookie_hmac); 2786 if (context->dtls.meth) 2787 BIO_meth_free(context->dtls.meth); 2788 if (context->dtls.bio_addr) 2789 BIO_ADDR_free(context->dtls.bio_addr); 2790#if !COAP_DISABLE_TCP 2791 if (context->tls.ctx) 2792 SSL_CTX_free(context->tls.ctx); 2793 if (context->tls.meth) 2794 BIO_meth_free(context->tls.meth); 2795#endif /* !COAP_DISABLE_TCP */ 2796 for (i = 0; i < context->sni_count; i++) { 2797 OPENSSL_free(context->sni_entry_list[i].sni); 2798#if OPENSSL_VERSION_NUMBER < 0x10101000L 2799 SSL_CTX_free(context->sni_entry_list[i].ctx); 2800#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ 2801 } 2802 if (context->sni_count) 2803 OPENSSL_free(context->sni_entry_list); 2804 for (i = 0; i < context->psk_sni_count; i++) { 2805 OPENSSL_free((char *)context->psk_sni_entry_list[i].sni); 2806#if OPENSSL_VERSION_NUMBER < 0x10101000L 2807 SSL_CTX_free(context->psk_sni_entry_list[i].ctx); 2808#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ 2809 } 2810 if (context->psk_sni_count) 2811 OPENSSL_free(context->psk_sni_entry_list); 2812 coap_free_type(COAP_STRING, context); 2813} 2814 2815#if COAP_SERVER_SUPPORT 2816void * 2817coap_dtls_new_server_session(coap_session_t *session) { 2818 BIO *nbio = NULL; 2819 SSL *nssl = NULL, *ssl = NULL; 2820 coap_ssl_data *data; 2821 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->context->dtls_context)->dtls; 2822 int r; 2823 const coap_bin_const_t *psk_hint; 2824 2825 nssl = SSL_new(dtls->ctx); 2826 if (!nssl) 2827 goto error; 2828 nbio = BIO_new(dtls->meth); 2829 if (!nbio) 2830 goto error; 2831 SSL_set_bio(nssl, nbio, nbio); 2832 SSL_set_app_data(nssl, NULL); 2833 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE); 2834 SSL_set_mtu(nssl, (long)session->mtu); 2835 ssl = dtls->ssl; 2836 dtls->ssl = nssl; 2837 nssl = NULL; 2838 SSL_set_app_data(ssl, session); 2839 2840 data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl)); 2841 data->session = session; 2842 2843 /* hint may get updated if/when handling SNI callback */ 2844 psk_hint = coap_get_session_server_psk_hint(session); 2845 if (psk_hint != NULL && psk_hint->length) { 2846 char *hint = OPENSSL_malloc(psk_hint->length + 1); 2847 2848 if (hint) { 2849 memcpy(hint, psk_hint->s, psk_hint->length); 2850 hint[psk_hint->length] = '\000'; 2851 SSL_use_psk_identity_hint(ssl, hint); 2852 OPENSSL_free(hint); 2853 } else { 2854 coap_log_warn("hint malloc failure\n"); 2855 } 2856 } 2857 2858 r = SSL_accept(ssl); 2859 if (r == -1) { 2860 int err = SSL_get_error(ssl, r); 2861 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) 2862 r = 0; 2863 } 2864 2865 if (r == 0) { 2866 SSL_free(ssl); 2867 return NULL; 2868 } 2869 2870 return ssl; 2871 2872error: 2873 if (nssl) 2874 SSL_free(nssl); 2875 return NULL; 2876} 2877#endif /* COAP_SERVER_SUPPORT */ 2878 2879#if COAP_CLIENT_SUPPORT 2880static int 2881setup_client_ssl_session(coap_session_t *session, SSL *ssl 2882 ) { 2883 coap_openssl_context_t *context = 2884 ((coap_openssl_context_t *)session->context->dtls_context); 2885 2886 if (context->psk_pki_enabled & IS_PSK) { 2887 coap_dtls_cpsk_t *setup_data = &session->cpsk_setup_data; 2888 2889 /* Issue SNI if requested */ 2890 if (setup_data->client_sni && 2891 SSL_set_tlsext_host_name(ssl, setup_data->client_sni) != 1) { 2892 coap_log_warn("SSL_set_tlsext_host_name: set '%s' failed", 2893 setup_data->client_sni); 2894 } 2895 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback); 2896#if COAP_SERVER_SUPPORT 2897 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback); 2898#endif /* COAP_SERVER_SUPPORT */ 2899 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS); 2900 if (setup_data->validate_ih_call_back) { 2901 if (session->proto == COAP_PROTO_DTLS) { 2902 SSL_set_max_proto_version(ssl, DTLS1_2_VERSION); 2903 } 2904#if !COAP_DISABLE_TCP 2905 else { 2906 SSL_set_max_proto_version(ssl, TLS1_2_VERSION); 2907 } 2908#endif /* !COAP_DISABLE_TCP */ 2909 coap_log_debug("CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n"); 2910 } 2911 } 2912 if (context->psk_pki_enabled & IS_PKI) { 2913 coap_dtls_pki_t *setup_data = &context->setup_data; 2914 if (!setup_pki_ssl(ssl, setup_data, COAP_DTLS_ROLE_CLIENT)) 2915 return 0; 2916 /* libcoap is managing (D)TLS connection based on setup_data options */ 2917#if !COAP_DISABLE_TCP 2918 if (session->proto == COAP_PROTO_TLS) 2919 SSL_set_alpn_protos(ssl, coap_alpn, sizeof(coap_alpn)); 2920#endif /* !COAP_DISABLE_TCP */ 2921 2922 /* Issue SNI if requested */ 2923 if (setup_data->client_sni && 2924 SSL_set_tlsext_host_name(ssl, setup_data->client_sni) != 1) { 2925 coap_log_warn("SSL_set_tlsext_host_name: set '%s' failed", 2926 setup_data->client_sni); 2927 } 2928 /* Certificate Revocation */ 2929 if (setup_data->check_cert_revocation) { 2930 X509_VERIFY_PARAM *param; 2931 2932 param = X509_VERIFY_PARAM_new(); 2933 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); 2934 SSL_set1_param(ssl, param); 2935 X509_VERIFY_PARAM_free(param); 2936 } 2937 2938 /* Verify Peer */ 2939 if (setup_data->verify_peer_cert) 2940 SSL_set_verify(ssl, 2941 SSL_VERIFY_PEER | 2942 SSL_VERIFY_CLIENT_ONCE | 2943 SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 2944 tls_verify_call_back); 2945 else 2946 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back); 2947 2948 /* Check CA Chain */ 2949 if (setup_data->cert_chain_validation) 2950 SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth + 1); 2951 2952 } 2953 return 1; 2954} 2955 2956void * 2957coap_dtls_new_client_session(coap_session_t *session) { 2958 BIO *bio = NULL; 2959 SSL *ssl = NULL; 2960 coap_ssl_data *data; 2961 int r; 2962 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->context->dtls_context); 2963 coap_dtls_context_t *dtls = &context->dtls; 2964 2965 ssl = SSL_new(dtls->ctx); 2966 if (!ssl) 2967 goto error; 2968 bio = BIO_new(dtls->meth); 2969 if (!bio) 2970 goto error; 2971 data = (coap_ssl_data *)BIO_get_data(bio); 2972 data->session = session; 2973 SSL_set_bio(ssl, bio, bio); 2974 SSL_set_app_data(ssl, session); 2975 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE); 2976 SSL_set_mtu(ssl, (long)session->mtu); 2977 2978 if (!setup_client_ssl_session(session, ssl)) 2979 goto error; 2980 2981 session->dtls_timeout_count = 0; 2982 2983 r = SSL_connect(ssl); 2984 if (r == -1) { 2985 int ret = SSL_get_error(ssl, r); 2986 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) 2987 r = 0; 2988 } 2989 2990 if (r == 0) 2991 goto error; 2992 2993 session->tls = ssl; 2994 return ssl; 2995 2996error: 2997 if (ssl) 2998 SSL_free(ssl); 2999 return NULL; 3000} 3001 3002void 3003coap_dtls_session_update_mtu(coap_session_t *session) { 3004 SSL *ssl = (SSL *)session->tls; 3005 if (ssl) 3006 SSL_set_mtu(ssl, (long)session->mtu); 3007} 3008#endif /* COAP_CLIENT_SUPPORT */ 3009 3010void 3011coap_dtls_free_session(coap_session_t *session) { 3012 SSL *ssl = (SSL *)session->tls; 3013 if (ssl) { 3014 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) { 3015 int r = SSL_shutdown(ssl); 3016 if (r == 0) 3017 r = SSL_shutdown(ssl); 3018 } 3019 SSL_free(ssl); 3020 session->tls = NULL; 3021 if (session->context) 3022 coap_handle_event(session->context, COAP_EVENT_DTLS_CLOSED, session); 3023 } 3024} 3025 3026ssize_t 3027coap_dtls_send(coap_session_t *session, 3028 const uint8_t *data, size_t data_len) { 3029 int r; 3030 SSL *ssl = (SSL *)session->tls; 3031 3032 assert(ssl != NULL); 3033 3034 session->dtls_event = -1; 3035 r = SSL_write(ssl, data, (int)data_len); 3036 3037 if (r <= 0) { 3038 int err = SSL_get_error(ssl, r); 3039 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { 3040 r = 0; 3041 } else { 3042 coap_log_warn("coap_dtls_send: cannot send PDU\n"); 3043 if (err == SSL_ERROR_ZERO_RETURN) 3044 session->dtls_event = COAP_EVENT_DTLS_CLOSED; 3045 else if (err == SSL_ERROR_SSL) 3046 session->dtls_event = COAP_EVENT_DTLS_ERROR; 3047 r = -1; 3048 } 3049 } 3050 3051 if (session->dtls_event >= 0) { 3052 /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */ 3053 if (session->dtls_event != COAP_EVENT_DTLS_CLOSED) 3054 coap_handle_event(session->context, session->dtls_event, session); 3055 if (session->dtls_event == COAP_EVENT_DTLS_ERROR || 3056 session->dtls_event == COAP_EVENT_DTLS_CLOSED) { 3057 coap_session_disconnected(session, COAP_NACK_TLS_FAILED); 3058 r = -1; 3059 } 3060 } 3061 3062 if (r > 0) { 3063 if (r == (ssize_t)data_len) 3064 coap_log_debug("* %s: dtls: sent %4d bytes\n", 3065 coap_session_str(session), r); 3066 else 3067 coap_log_debug("* %s: dtls: sent %4d of %4zd bytes\n", 3068 coap_session_str(session), r, data_len); 3069 } 3070 return r; 3071} 3072 3073int 3074coap_dtls_is_context_timeout(void) { 3075 return 0; 3076} 3077 3078coap_tick_t 3079coap_dtls_get_context_timeout(void *dtls_context) { 3080 (void)dtls_context; 3081 return 0; 3082} 3083 3084coap_tick_t 3085coap_dtls_get_timeout(coap_session_t *session, coap_tick_t now COAP_UNUSED) { 3086 SSL *ssl = (SSL *)session->tls; 3087 coap_ssl_data *ssl_data; 3088 3089 assert(ssl != NULL && session->state == COAP_SESSION_STATE_HANDSHAKE); 3090 ssl_data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl)); 3091 return ssl_data->timeout; 3092} 3093 3094/* 3095 * return 1 timed out 3096 * 0 still timing out 3097 */ 3098int 3099coap_dtls_handle_timeout(coap_session_t *session) { 3100 SSL *ssl = (SSL *)session->tls; 3101 3102 assert(ssl != NULL && session->state == COAP_SESSION_STATE_HANDSHAKE); 3103 if ((++session->dtls_timeout_count > session->max_retransmit) || 3104 (DTLSv1_handle_timeout(ssl) < 0)) { 3105 /* Too many retries */ 3106 coap_session_disconnected(session, COAP_NACK_TLS_FAILED); 3107 return 1; 3108 } 3109 return 0; 3110} 3111 3112#if COAP_SERVER_SUPPORT 3113int 3114coap_dtls_hello(coap_session_t *session, 3115 const uint8_t *data, size_t data_len) { 3116 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->context->dtls_context)->dtls; 3117 coap_ssl_data *ssl_data; 3118 int r; 3119 3120 SSL_set_mtu(dtls->ssl, (long)session->mtu); 3121 ssl_data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(dtls->ssl)); 3122 assert(ssl_data != NULL); 3123 if (ssl_data->pdu_len) { 3124 coap_log_err("** %s: Previous data not read %u bytes\n", 3125 coap_session_str(session), ssl_data->pdu_len); 3126 } 3127 ssl_data->session = session; 3128 ssl_data->pdu = data; 3129 ssl_data->pdu_len = (unsigned)data_len; 3130 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr); 3131 if (r <= 0) { 3132 int err = SSL_get_error(dtls->ssl, r); 3133 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { 3134 /* Got a ClientHello, sent-out a VerifyRequest */ 3135 r = 0; 3136 } 3137 } else { 3138 /* Got a valid answer to a VerifyRequest */ 3139 r = 1; 3140 } 3141 3142 /* 3143 * Cannot check if data is left on the stack in error as DTLSv1_listen() 3144 * only does a 'peek' read of the incoming data. 3145 * 3146 */ 3147 return r; 3148} 3149#endif /* COAP_SERVER_SUPPORT */ 3150 3151int 3152coap_dtls_receive(coap_session_t *session, const uint8_t *data, size_t data_len) { 3153 coap_ssl_data *ssl_data; 3154 SSL *ssl = (SSL *)session->tls; 3155 int r; 3156 3157 assert(ssl != NULL); 3158 3159 int in_init = SSL_in_init(ssl); 3160 uint8_t pdu[COAP_RXBUFFER_SIZE]; 3161 ssl_data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl)); 3162 assert(ssl_data != NULL); 3163 3164 if (ssl_data->pdu_len) { 3165 coap_log_err("** %s: Previous data not read %u bytes\n", 3166 coap_session_str(session), ssl_data->pdu_len); 3167 } 3168 ssl_data->pdu = data; 3169 ssl_data->pdu_len = (unsigned)data_len; 3170 3171 session->dtls_event = -1; 3172 r = SSL_read(ssl, pdu, (int)sizeof(pdu)); 3173 if (r > 0) { 3174 r = coap_handle_dgram(session->context, session, pdu, (size_t)r); 3175 goto finished; 3176 } else { 3177 int err = SSL_get_error(ssl, r); 3178 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { 3179 if (in_init && SSL_is_init_finished(ssl)) { 3180 coap_dtls_log(COAP_LOG_INFO, "* %s: Using cipher: %s\n", 3181 coap_session_str(session), SSL_get_cipher_name(ssl)); 3182 coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); 3183 session->sock.lfunc[COAP_LAYER_TLS].l_establish(session); 3184 } 3185 r = 0; 3186 } else { 3187 if (err == SSL_ERROR_ZERO_RETURN) /* Got a close notify alert from the remote side */ 3188 session->dtls_event = COAP_EVENT_DTLS_CLOSED; 3189 else if (err == SSL_ERROR_SSL) 3190 session->dtls_event = COAP_EVENT_DTLS_ERROR; 3191 r = -1; 3192 } 3193 if (session->dtls_event >= 0) { 3194 /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */ 3195 if (session->dtls_event != COAP_EVENT_DTLS_CLOSED) 3196 coap_handle_event(session->context, session->dtls_event, session); 3197 if (session->dtls_event == COAP_EVENT_DTLS_ERROR || 3198 session->dtls_event == COAP_EVENT_DTLS_CLOSED) { 3199 coap_session_disconnected(session, COAP_NACK_TLS_FAILED); 3200 ssl_data = NULL; 3201 r = -1; 3202 } 3203 } 3204 } 3205 3206finished: 3207 if (ssl_data && ssl_data->pdu_len) { 3208 /* pdu data is held on stack which will not stay there */ 3209 coap_log_debug("coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len); 3210 ssl_data->pdu_len = 0; 3211 ssl_data->pdu = NULL; 3212 } 3213 if (r > 0) { 3214 coap_log_debug("* %s: dtls: recv %4d bytes\n", 3215 coap_session_str(session), r); 3216 } 3217 return r; 3218} 3219 3220unsigned int 3221coap_dtls_get_overhead(coap_session_t *session) { 3222 unsigned int overhead = 37; 3223 const SSL_CIPHER *s_ciph = NULL; 3224 if (session->tls != NULL) 3225 s_ciph = SSL_get_current_cipher(session->tls); 3226 if (s_ciph) { 3227 unsigned int ivlen, maclen, blocksize = 1, pad = 0; 3228 3229 const EVP_CIPHER *e_ciph; 3230 const EVP_MD *e_md; 3231 char cipher[128]; 3232 3233 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph)); 3234 3235 switch (EVP_CIPHER_mode(e_ciph)) { 3236 case EVP_CIPH_GCM_MODE: 3237 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; 3238 maclen = EVP_GCM_TLS_TAG_LEN; 3239 break; 3240 3241 case EVP_CIPH_CCM_MODE: 3242 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; 3243 SSL_CIPHER_description(s_ciph, cipher, sizeof(cipher)); 3244 if (strstr(cipher, "CCM8")) 3245 maclen = 8; 3246 else 3247 maclen = 16; 3248 break; 3249 3250 case EVP_CIPH_CBC_MODE: 3251 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph)); 3252 blocksize = EVP_CIPHER_block_size(e_ciph); 3253 ivlen = EVP_CIPHER_iv_length(e_ciph); 3254 pad = 1; 3255 maclen = EVP_MD_size(e_md); 3256 break; 3257 3258 case EVP_CIPH_STREAM_CIPHER: 3259 /* Seen with PSK-CHACHA20-POLY1305 */ 3260 ivlen = 8; 3261 maclen = 8; 3262 break; 3263 3264 default: 3265 SSL_CIPHER_description(s_ciph, cipher, sizeof(cipher)); 3266 coap_log_warn("Unknown overhead for DTLS with cipher %s\n", 3267 cipher); 3268 ivlen = 8; 3269 maclen = 16; 3270 break; 3271 } 3272 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad; 3273 } 3274 return overhead; 3275} 3276 3277#if !COAP_DISABLE_TCP 3278#if COAP_CLIENT_SUPPORT 3279void * 3280coap_tls_new_client_session(coap_session_t *session) { 3281 BIO *bio = NULL; 3282 SSL *ssl = NULL; 3283 int r; 3284 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->context->dtls_context); 3285 coap_tls_context_t *tls = &context->tls; 3286 3287 ssl = SSL_new(tls->ctx); 3288 if (!ssl) 3289 goto error; 3290 bio = BIO_new(tls->meth); 3291 if (!bio) 3292 goto error; 3293 BIO_set_data(bio, session); 3294 SSL_set_bio(ssl, bio, bio); 3295 SSL_set_app_data(ssl, session); 3296 3297 if (!setup_client_ssl_session(session, ssl)) 3298 return 0; 3299 3300 r = SSL_connect(ssl); 3301 if (r == -1) { 3302 int ret = SSL_get_error(ssl, r); 3303 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) 3304 r = 0; 3305 if (ret == SSL_ERROR_WANT_READ) 3306 session->sock.flags |= COAP_SOCKET_WANT_READ; 3307 if (ret == SSL_ERROR_WANT_WRITE) { 3308 session->sock.flags |= COAP_SOCKET_WANT_WRITE; 3309#ifdef COAP_EPOLL_SUPPORT 3310 coap_epoll_ctl_mod(&session->sock, 3311 EPOLLOUT | 3312 ((session->sock.flags & COAP_SOCKET_WANT_READ) ? 3313 EPOLLIN : 0), 3314 __func__); 3315#endif /* COAP_EPOLL_SUPPORT */ 3316 } 3317 } 3318 3319 if (r == 0) 3320 goto error; 3321 3322 session->tls = ssl; 3323 if (SSL_is_init_finished(ssl)) { 3324 coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); 3325 session->sock.lfunc[COAP_LAYER_TLS].l_establish(session); 3326 } 3327 3328 return ssl; 3329 3330error: 3331 if (ssl) 3332 SSL_free(ssl); 3333 return NULL; 3334} 3335#endif /* COAP_CLIENT_SUPPORT */ 3336 3337#if COAP_SERVER_SUPPORT 3338void * 3339coap_tls_new_server_session(coap_session_t *session) { 3340 BIO *bio = NULL; 3341 SSL *ssl = NULL; 3342 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->context->dtls_context)->tls; 3343 int r; 3344 const coap_bin_const_t *psk_hint; 3345 3346 ssl = SSL_new(tls->ctx); 3347 if (!ssl) 3348 goto error; 3349 bio = BIO_new(tls->meth); 3350 if (!bio) 3351 goto error; 3352 BIO_set_data(bio, session); 3353 SSL_set_bio(ssl, bio, bio); 3354 SSL_set_app_data(ssl, session); 3355 3356 psk_hint = coap_get_session_server_psk_hint(session); 3357 if (psk_hint != NULL && psk_hint->length) { 3358 char *hint = OPENSSL_malloc(psk_hint->length + 1); 3359 3360 if (hint) { 3361 memcpy(hint, psk_hint->s, psk_hint->length); 3362 hint[psk_hint->length] = '\000'; 3363 SSL_use_psk_identity_hint(ssl, hint); 3364 OPENSSL_free(hint); 3365 } else { 3366 coap_log_warn("hint malloc failure\n"); 3367 } 3368 } 3369 3370 r = SSL_accept(ssl); 3371 if (r == -1) { 3372 int err = SSL_get_error(ssl, r); 3373 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) 3374 r = 0; 3375 if (err == SSL_ERROR_WANT_READ) 3376 session->sock.flags |= COAP_SOCKET_WANT_READ; 3377 if (err == SSL_ERROR_WANT_WRITE) { 3378 session->sock.flags |= COAP_SOCKET_WANT_WRITE; 3379#ifdef COAP_EPOLL_SUPPORT 3380 coap_epoll_ctl_mod(&session->sock, 3381 EPOLLOUT | 3382 ((session->sock.flags & COAP_SOCKET_WANT_READ) ? 3383 EPOLLIN : 0), 3384 __func__); 3385#endif /* COAP_EPOLL_SUPPORT */ 3386 } 3387 } 3388 3389 if (r == 0) 3390 goto error; 3391 3392 session->tls = ssl; 3393 if (SSL_is_init_finished(ssl)) { 3394 coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); 3395 session->sock.lfunc[COAP_LAYER_TLS].l_establish(session); 3396 } 3397 3398 return ssl; 3399 3400error: 3401 if (ssl) 3402 SSL_free(ssl); 3403 return NULL; 3404} 3405#endif /* COAP_SERVER_SUPPORT */ 3406 3407void 3408coap_tls_free_session(coap_session_t *session) { 3409 SSL *ssl = (SSL *)session->tls; 3410 if (ssl) { 3411 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) { 3412 int r = SSL_shutdown(ssl); 3413 if (r == 0) 3414 r = SSL_shutdown(ssl); 3415 } 3416 SSL_free(ssl); 3417 session->tls = NULL; 3418 if (session->context) 3419 coap_handle_event(session->context, COAP_EVENT_DTLS_CLOSED, session); 3420 } 3421} 3422 3423/* 3424 * strm 3425 * return +ve Number of bytes written. 3426 * -1 Error (error in errno). 3427 */ 3428ssize_t 3429coap_tls_write(coap_session_t *session, const uint8_t *data, size_t data_len) { 3430 SSL *ssl = (SSL *)session->tls; 3431 int r, in_init; 3432 3433 if (ssl == NULL) 3434 return -1; 3435 3436 in_init = !SSL_is_init_finished(ssl); 3437 session->dtls_event = -1; 3438 r = SSL_write(ssl, data, (int)data_len); 3439 3440 if (r <= 0) { 3441 int err = SSL_get_error(ssl, r); 3442 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { 3443 if (in_init && SSL_is_init_finished(ssl)) { 3444 coap_dtls_log(COAP_LOG_INFO, "* %s: Using cipher: %s\n", 3445 coap_session_str(session), SSL_get_cipher_name(ssl)); 3446 coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); 3447 session->sock.lfunc[COAP_LAYER_TLS].l_establish(session); 3448 } 3449 if (err == SSL_ERROR_WANT_READ) 3450 session->sock.flags |= COAP_SOCKET_WANT_READ; 3451 else if (err == SSL_ERROR_WANT_WRITE) { 3452 session->sock.flags |= COAP_SOCKET_WANT_WRITE; 3453#ifdef COAP_EPOLL_SUPPORT 3454 coap_epoll_ctl_mod(&session->sock, 3455 EPOLLOUT | 3456 ((session->sock.flags & COAP_SOCKET_WANT_READ) ? 3457 EPOLLIN : 0), 3458 __func__); 3459#endif /* COAP_EPOLL_SUPPORT */ 3460 } 3461 r = 0; 3462 } else { 3463 coap_log_info("***%s: coap_tls_write: cannot send PDU\n", 3464 coap_session_str(session)); 3465 if (err == SSL_ERROR_ZERO_RETURN) 3466 session->dtls_event = COAP_EVENT_DTLS_CLOSED; 3467 else if (err == SSL_ERROR_SSL) 3468 session->dtls_event = COAP_EVENT_DTLS_ERROR; 3469 r = -1; 3470 } 3471 } else if (in_init && SSL_is_init_finished(ssl)) { 3472 coap_dtls_log(COAP_LOG_INFO, "* %s: Using cipher: %s\n", 3473 coap_session_str(session), SSL_get_cipher_name(ssl)); 3474 coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); 3475 session->sock.lfunc[COAP_LAYER_TLS].l_establish(session); 3476 } 3477 3478 if (session->dtls_event >= 0) { 3479 /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */ 3480 if (session->dtls_event != COAP_EVENT_DTLS_CLOSED) 3481 coap_handle_event(session->context, session->dtls_event, session); 3482 if (session->dtls_event == COAP_EVENT_DTLS_ERROR || 3483 session->dtls_event == COAP_EVENT_DTLS_CLOSED) { 3484 coap_session_disconnected(session, COAP_NACK_TLS_FAILED); 3485 r = -1; 3486 } 3487 } 3488 3489 if (r >= 0) { 3490 if (r == (ssize_t)data_len) 3491 coap_log_debug("* %s: tls: sent %4d bytes\n", 3492 coap_session_str(session), r); 3493 else 3494 coap_log_debug("* %s: tls: sent %4d of %4zd bytes\n", 3495 coap_session_str(session), r, data_len); 3496 } 3497 return r; 3498} 3499 3500/* 3501 * strm 3502 * return >=0 Number of bytes read. 3503 * -1 Error (error in errno). 3504 */ 3505ssize_t 3506coap_tls_read(coap_session_t *session, uint8_t *data, size_t data_len) { 3507 SSL *ssl = (SSL *)session->tls; 3508 int r, in_init; 3509 3510 if (ssl == NULL) { 3511 errno = ENXIO; 3512 return -1; 3513 } 3514 3515 in_init = !SSL_is_init_finished(ssl); 3516 session->dtls_event = -1; 3517 r = SSL_read(ssl, data, (int)data_len); 3518 if (r <= 0) { 3519 int err = SSL_get_error(ssl, r); 3520 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { 3521 if (in_init && SSL_is_init_finished(ssl)) { 3522 coap_dtls_log(COAP_LOG_INFO, "* %s: Using cipher: %s\n", 3523 coap_session_str(session), SSL_get_cipher_name(ssl)); 3524 coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); 3525 session->sock.lfunc[COAP_LAYER_TLS].l_establish(session); 3526 } 3527 if (err == SSL_ERROR_WANT_READ) 3528 session->sock.flags |= COAP_SOCKET_WANT_READ; 3529 if (err == SSL_ERROR_WANT_WRITE) { 3530 session->sock.flags |= COAP_SOCKET_WANT_WRITE; 3531#ifdef COAP_EPOLL_SUPPORT 3532 coap_epoll_ctl_mod(&session->sock, 3533 EPOLLOUT | 3534 ((session->sock.flags & COAP_SOCKET_WANT_READ) ? 3535 EPOLLIN : 0), 3536 __func__); 3537#endif /* COAP_EPOLL_SUPPORT */ 3538 } 3539 r = 0; 3540 } else { 3541 if (err == SSL_ERROR_ZERO_RETURN) /* Got a close notify alert from the remote side */ 3542 session->dtls_event = COAP_EVENT_DTLS_CLOSED; 3543 else if (err == SSL_ERROR_SSL) 3544 session->dtls_event = COAP_EVENT_DTLS_ERROR; 3545 r = -1; 3546 } 3547 } else if (in_init && SSL_is_init_finished(ssl)) { 3548 coap_dtls_log(COAP_LOG_INFO, "* %s: Using cipher: %s\n", 3549 coap_session_str(session), SSL_get_cipher_name(ssl)); 3550 coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session); 3551 session->sock.lfunc[COAP_LAYER_TLS].l_establish(session); 3552 } 3553 3554 if (session->dtls_event >= 0) { 3555 /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */ 3556 if (session->dtls_event != COAP_EVENT_DTLS_CLOSED) 3557 coap_handle_event(session->context, session->dtls_event, session); 3558 if (session->dtls_event == COAP_EVENT_DTLS_ERROR || 3559 session->dtls_event == COAP_EVENT_DTLS_CLOSED) { 3560 coap_session_disconnected(session, COAP_NACK_TLS_FAILED); 3561 r = -1; 3562 } 3563 } 3564 3565 if (r > 0) { 3566 coap_log_debug("* %s: tls: recv %4d bytes\n", 3567 coap_session_str(session), r); 3568 } 3569 return r; 3570} 3571#endif /* !COAP_DISABLE_TCP */ 3572 3573#if COAP_SERVER_SUPPORT 3574coap_digest_ctx_t * 3575coap_digest_setup(void) { 3576 EVP_MD_CTX *digest_ctx = EVP_MD_CTX_new(); 3577 3578 if (digest_ctx) { 3579 EVP_DigestInit_ex(digest_ctx, EVP_sha256(), NULL); 3580 } 3581 return digest_ctx; 3582} 3583 3584void 3585coap_digest_free(coap_digest_ctx_t *digest_ctx) { 3586 EVP_MD_CTX_free(digest_ctx); 3587} 3588 3589int 3590coap_digest_update(coap_digest_ctx_t *digest_ctx, 3591 const uint8_t *data, 3592 size_t data_len) { 3593 return EVP_DigestUpdate(digest_ctx, data, data_len); 3594} 3595 3596int 3597coap_digest_final(coap_digest_ctx_t *digest_ctx, 3598 coap_digest_t *digest_buffer) { 3599 unsigned int size = sizeof(coap_digest_t); 3600 int ret = EVP_DigestFinal_ex(digest_ctx, (uint8_t *)digest_buffer, &size); 3601 3602 coap_digest_free(digest_ctx); 3603 return ret; 3604} 3605#endif /* COAP_SERVER_SUPPORT */ 3606 3607#if COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT 3608static void 3609coap_crypto_output_errors(const char *prefix) { 3610#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_WARN 3611 (void)prefix; 3612#else /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_WARN */ 3613 unsigned long e; 3614 3615 while ((e = ERR_get_error())) 3616 coap_log_warn("%s: %s%s\n", 3617 prefix, 3618 ERR_reason_error_string(e), 3619 ssl_function_definition(e)); 3620#endif /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_WARN */ 3621} 3622#endif /* COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT */ 3623 3624#if COAP_WS_SUPPORT 3625/* 3626 * The struct hash_algs and the function get_hash_alg() are used to 3627 * determine which hash type to use for creating the required hash object. 3628 */ 3629static struct hash_algs { 3630 cose_alg_t alg; 3631 const EVP_MD *(*get_hash)(void); 3632 size_t length; /* in bytes */ 3633} hashs[] = { 3634 {COSE_ALGORITHM_SHA_1, EVP_sha1, 20}, 3635 {COSE_ALGORITHM_SHA_256_64, EVP_sha256, 8}, 3636 {COSE_ALGORITHM_SHA_256_256, EVP_sha256, 32}, 3637 {COSE_ALGORITHM_SHA_512, EVP_sha512, 64}, 3638}; 3639 3640static const EVP_MD * 3641get_hash_alg(cose_alg_t alg, size_t *length) { 3642 size_t idx; 3643 3644 for (idx = 0; idx < sizeof(hashs) / sizeof(struct hash_algs); idx++) { 3645 if (hashs[idx].alg == alg) { 3646 *length = hashs[idx].length; 3647 return hashs[idx].get_hash(); 3648 } 3649 } 3650 coap_log_debug("get_hash_alg: COSE hash %d not supported\n", alg); 3651 return NULL; 3652} 3653 3654int 3655coap_crypto_hash(cose_alg_t alg, 3656 const coap_bin_const_t *data, 3657 coap_bin_const_t **hash) { 3658 unsigned int length; 3659 const EVP_MD *evp_md; 3660 EVP_MD_CTX *evp_ctx = NULL; 3661 coap_binary_t *dummy = NULL; 3662 size_t hash_length; 3663 3664 if ((evp_md = get_hash_alg(alg, &hash_length)) == NULL) { 3665 coap_log_debug("coap_crypto_hash: algorithm %d not supported\n", alg); 3666 return 0; 3667 } 3668 evp_ctx = EVP_MD_CTX_new(); 3669 if (evp_ctx == NULL) 3670 goto error; 3671 if (EVP_DigestInit_ex(evp_ctx, evp_md, NULL) == 0) 3672 goto error; 3673 ; 3674 if (EVP_DigestUpdate(evp_ctx, data->s, data->length) == 0) 3675 goto error; 3676 ; 3677 dummy = coap_new_binary(EVP_MAX_MD_SIZE); 3678 if (dummy == NULL) 3679 goto error; 3680 if (EVP_DigestFinal_ex(evp_ctx, dummy->s, &length) == 0) 3681 goto error; 3682 dummy->length = length; 3683 if (hash_length < dummy->length) 3684 dummy->length = hash_length; 3685 *hash = (coap_bin_const_t *)(dummy); 3686 EVP_MD_CTX_free(evp_ctx); 3687 return 1; 3688 3689error: 3690 coap_crypto_output_errors("coap_crypto_hash"); 3691 coap_delete_binary(dummy); 3692 if (evp_ctx) 3693 EVP_MD_CTX_free(evp_ctx); 3694 return 0; 3695} 3696#endif /* COAP_WS_SUPPORT */ 3697 3698#if COAP_OSCORE_SUPPORT 3699int 3700coap_oscore_is_supported(void) { 3701 return 1; 3702} 3703 3704#include <openssl/evp.h> 3705#include <openssl/hmac.h> 3706 3707/* 3708 * The struct cipher_algs and the function get_cipher_alg() are used to 3709 * determine which cipher type to use for creating the required cipher 3710 * suite object. 3711 */ 3712static struct cipher_algs { 3713 cose_alg_t alg; 3714 const EVP_CIPHER *(*get_cipher)(void); 3715} ciphers[] = {{COSE_ALGORITHM_AES_CCM_16_64_128, EVP_aes_128_ccm}, 3716 {COSE_ALGORITHM_AES_CCM_16_64_256, EVP_aes_256_ccm} 3717}; 3718 3719static const EVP_CIPHER * 3720get_cipher_alg(cose_alg_t alg) { 3721 size_t idx; 3722 3723 for (idx = 0; idx < sizeof(ciphers) / sizeof(struct cipher_algs); idx++) { 3724 if (ciphers[idx].alg == alg) 3725 return ciphers[idx].get_cipher(); 3726 } 3727 coap_log_debug("get_cipher_alg: COSE cipher %d not supported\n", alg); 3728 return NULL; 3729} 3730 3731/* 3732 * The struct hmac_algs and the function get_hmac_alg() are used to 3733 * determine which hmac type to use for creating the required hmac 3734 * suite object. 3735 */ 3736static struct hmac_algs { 3737 cose_hmac_alg_t hmac_alg; 3738 const EVP_MD *(*get_hmac)(void); 3739} hmacs[] = { 3740 {COSE_HMAC_ALG_HMAC256_256, EVP_sha256}, 3741 {COSE_HMAC_ALG_HMAC384_384, EVP_sha384}, 3742 {COSE_HMAC_ALG_HMAC512_512, EVP_sha512}, 3743}; 3744 3745static const EVP_MD * 3746get_hmac_alg(cose_hmac_alg_t hmac_alg) { 3747 size_t idx; 3748 3749 for (idx = 0; idx < sizeof(hmacs) / sizeof(struct hmac_algs); idx++) { 3750 if (hmacs[idx].hmac_alg == hmac_alg) 3751 return hmacs[idx].get_hmac(); 3752 } 3753 coap_log_debug("get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg); 3754 return NULL; 3755} 3756 3757int 3758coap_crypto_check_cipher_alg(cose_alg_t alg) { 3759 return get_cipher_alg(alg) != NULL; 3760} 3761 3762int 3763coap_crypto_check_hkdf_alg(cose_hkdf_alg_t hkdf_alg) { 3764 cose_hmac_alg_t hmac_alg; 3765 3766 if (!cose_get_hmac_alg_for_hkdf(hkdf_alg, &hmac_alg)) 3767 return 0; 3768 return get_hmac_alg(hmac_alg) != NULL; 3769} 3770 3771#define C(Func) \ 3772 if (1 != (Func)) { \ 3773 goto error; \ 3774 } 3775 3776int 3777coap_crypto_aead_encrypt(const coap_crypto_param_t *params, 3778 coap_bin_const_t *data, 3779 coap_bin_const_t *aad, 3780 uint8_t *result, 3781 size_t *max_result_len) { 3782 const EVP_CIPHER *cipher; 3783 const coap_crypto_aes_ccm_t *ccm; 3784 int tmp; 3785 int result_len = (int)(*max_result_len & INT_MAX); 3786 3787 if (data == NULL) 3788 return 0; 3789 3790 assert(params != NULL); 3791 if (!params || ((cipher = get_cipher_alg(params->alg)) == NULL)) { 3792 return 0; 3793 } 3794 3795 /* TODO: set evp_md depending on params->alg */ 3796 ccm = ¶ms->params.aes; 3797 3798 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); 3799 3800 /* EVP_CIPHER_CTX_init(ctx); */ 3801 C(EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL)); 3802 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (int)ccm->l, NULL)); 3803 C(EVP_CIPHER_CTX_ctrl(ctx, 3804 EVP_CTRL_AEAD_SET_IVLEN, 3805 (int)(15 - ccm->l), 3806 NULL)); 3807 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (int)ccm->tag_len, NULL)); 3808 C(EVP_EncryptInit_ex(ctx, NULL, NULL, ccm->key.s, ccm->nonce)); 3809 /* C(EVP_CIPHER_CTX_set_padding(ctx, 0)); */ 3810 3811 C(EVP_EncryptUpdate(ctx, NULL, &result_len, NULL, (int)data->length)); 3812 if (aad && aad->s && (aad->length > 0)) { 3813 C(EVP_EncryptUpdate(ctx, NULL, &result_len, aad->s, (int)aad->length)); 3814 } 3815 C(EVP_EncryptUpdate(ctx, result, &result_len, data->s, (int)data->length)); 3816 /* C(EVP_EncryptFinal_ex(ctx, result + result_len, &tmp)); */ 3817 tmp = result_len; 3818 C(EVP_EncryptFinal_ex(ctx, result + result_len, &tmp)); 3819 result_len += tmp; 3820 3821 /* retrieve the tag */ 3822 C(EVP_CIPHER_CTX_ctrl(ctx, 3823 EVP_CTRL_CCM_GET_TAG, 3824 (int)ccm->tag_len, 3825 result + result_len)); 3826 3827 *max_result_len = result_len + ccm->tag_len; 3828 EVP_CIPHER_CTX_free(ctx); 3829 return 1; 3830 3831error: 3832 coap_crypto_output_errors("coap_crypto_aead_encrypt"); 3833 return 0; 3834} 3835 3836int 3837coap_crypto_aead_decrypt(const coap_crypto_param_t *params, 3838 coap_bin_const_t *data, 3839 coap_bin_const_t *aad, 3840 uint8_t *result, 3841 size_t *max_result_len) { 3842 const EVP_CIPHER *cipher; 3843 const coap_crypto_aes_ccm_t *ccm; 3844 int tmp; 3845 int len; 3846 const uint8_t *tag; 3847 uint8_t *rwtag; 3848 3849 if (data == NULL) 3850 return 0; 3851 3852 assert(params != NULL); 3853 if (!params || ((cipher = get_cipher_alg(params->alg)) == NULL)) { 3854 return 0; 3855 } 3856 3857 ccm = ¶ms->params.aes; 3858 3859 if (data->length < ccm->tag_len) { 3860 return 0; 3861 } else { 3862 tag = data->s + data->length - ccm->tag_len; 3863 data->length -= ccm->tag_len; 3864 /* Kludge to stop compiler warning */ 3865 memcpy(&rwtag, &tag, sizeof(rwtag)); 3866 } 3867 3868 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); 3869 3870 C(EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL)); 3871 C(EVP_CIPHER_CTX_ctrl(ctx, 3872 EVP_CTRL_AEAD_SET_IVLEN, 3873 (int)(15 - ccm->l), 3874 NULL)); 3875 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (int)ccm->tag_len, rwtag)); 3876 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (int)ccm->l, NULL)); 3877 /* C(EVP_CIPHER_CTX_set_padding(ctx, 0)); */ 3878 C(EVP_DecryptInit_ex(ctx, NULL, NULL, ccm->key.s, ccm->nonce)); 3879 3880 C(EVP_DecryptUpdate(ctx, NULL, &len, NULL, (int)data->length)); 3881 if (aad && aad->s && (aad->length > 0)) { 3882 C(EVP_DecryptUpdate(ctx, NULL, &len, aad->s, (int)aad->length)); 3883 } 3884 tmp = EVP_DecryptUpdate(ctx, result, &len, data->s, (int)data->length); 3885 EVP_CIPHER_CTX_free(ctx); 3886 if (tmp <= 0) { 3887 *max_result_len = 0; 3888 return 0; 3889 } 3890 *max_result_len = len; 3891 return 1; 3892 3893error: 3894 coap_crypto_output_errors("coap_crypto_aead_decrypt"); 3895 return 0; 3896} 3897 3898int 3899coap_crypto_hmac(cose_hmac_alg_t hmac_alg, 3900 coap_bin_const_t *key, 3901 coap_bin_const_t *data, 3902 coap_bin_const_t **hmac) { 3903 unsigned int result_len; 3904 const EVP_MD *evp_md; 3905 coap_binary_t *dummy = NULL; 3906 3907 assert(key); 3908 assert(data); 3909 assert(hmac); 3910 3911 if ((evp_md = get_hmac_alg(hmac_alg)) == 0) { 3912 coap_log_debug("coap_crypto_hmac: algorithm %d not supported\n", hmac_alg); 3913 return 0; 3914 } 3915 dummy = coap_new_binary(EVP_MAX_MD_SIZE); 3916 if (dummy == NULL) 3917 return 0; 3918 result_len = (unsigned int)dummy->length; 3919 if (HMAC(evp_md, 3920 key->s, 3921 (int)key->length, 3922 data->s, 3923 (int)data->length, 3924 dummy->s, 3925 &result_len)) { 3926 dummy->length = result_len; 3927 *hmac = (coap_bin_const_t *)dummy; 3928 return 1; 3929 } 3930 3931 coap_crypto_output_errors("coap_crypto_hmac"); 3932 return 0; 3933} 3934 3935#endif /* COAP_OSCORE_SUPPORT */ 3936 3937#else /* !COAP_WITH_LIBOPENSSL */ 3938 3939#ifdef __clang__ 3940/* Make compilers happy that do not like empty modules. As this function is 3941 * never used, we ignore -Wunused-function at the end of compiling this file 3942 */ 3943#pragma GCC diagnostic ignored "-Wunused-function" 3944#endif 3945static inline void 3946dummy(void) { 3947} 3948 3949#endif /* COAP_WITH_LIBOPENSSL */ 3950