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