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