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