xref: /third_party/libcoap/src/coap_openssl.c (revision c87c5fba)
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, &params, 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 = &params->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 = &params->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