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