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