libcoap  4.2.1
coap_openssl.c
Go to the documentation of this file.
1 /*
2 * coap_openssl.c -- Datagram Transport Layer Support for libcoap with openssl
3 *
4 * Copyright (C) 2017 Jean-Claude Michelou <jcm@spinetix.com>
5 * Copyright (C) 2018 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  */
43 #include <openssl/ssl.h>
44 #include <openssl/err.h>
45 #include <openssl/rand.h>
46 #include <openssl/hmac.h>
47 #include <openssl/x509v3.h>
48 
49 #ifdef COAP_EPOLL_SUPPORT
50 # include <sys/epoll.h>
51 #endif /* COAP_EPOLL_SUPPORT */
52 
53 #if OPENSSL_VERSION_NUMBER < 0x10100000L
54 #error Must be compiled against OpenSSL 1.1.0 or later
55 #endif
56 
57 #ifdef __GNUC__
58 #define UNUSED __attribute__((unused))
59 #else
60 #define UNUSED
61 #endif /* __GNUC__ */
62 
63 /* RFC6091/RFC7250 */
64 #ifndef TLSEXT_TYPE_client_certificate_type
65 #define TLSEXT_TYPE_client_certificate_type 19
66 #endif
67 #ifndef TLSEXT_TYPE_server_certificate_type
68 #define TLSEXT_TYPE_server_certificate_type 20
69 #endif
70 
71 #ifndef COAP_OPENSSL_CIPHERS
72 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
73 #define COAP_OPENSSL_CIPHERS "TLSv1.3:TLSv1.2:!NULL"
74 #else /* OPENSSL_VERSION_NUMBER < 0x10101000L */
75 #define COAP_OPENSSL_CIPHERS "TLSv1.2:!NULL"
76 #endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
77 #endif /*COAP_OPENSSL_CIPHERS */
78 
79 #ifndef COAP_OPENSSL_PSK_CIPHERS
80 #define COAP_OPENSSL_PSK_CIPHERS "PSK:!NULL"
81 #endif /*COAP_OPENSSL_PSK_CIPHERS */
82 
83 /* This structure encapsulates the OpenSSL context object. */
84 typedef struct coap_dtls_context_t {
85  SSL_CTX *ctx;
86  SSL *ssl; /* OpenSSL object for listening to connection requests */
87  HMAC_CTX *cookie_hmac;
88  BIO_METHOD *meth;
89  BIO_ADDR *bio_addr;
90 } coap_dtls_context_t;
91 
92 typedef struct coap_tls_context_t {
93  SSL_CTX *ctx;
94  BIO_METHOD *meth;
95 } coap_tls_context_t;
96 
97 #define IS_PSK 0x1
98 #define IS_PKI 0x2
99 
100 typedef struct sni_entry {
101  char *sni;
102 #if OPENSSL_VERSION_NUMBER < 0x10101000L
103  SSL_CTX *ctx;
104 #else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
105  coap_dtls_key_t pki_key;
106 #endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
107 } sni_entry;
108 
109 typedef struct coap_openssl_context_t {
110  coap_dtls_context_t dtls;
111  coap_tls_context_t tls;
112  coap_dtls_pki_t setup_data;
113  int psk_pki_enabled;
114  size_t sni_count;
115  sni_entry *sni_entry_list;
116 } coap_openssl_context_t;
117 
118 int coap_dtls_is_supported(void) {
119  if (SSLeay() < 0x10100000L) {
120  coap_log(LOG_WARNING, "OpenSSL version 1.1.0 or later is required\n");
121  return 0;
122  }
123 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
124  /*
125  * For 1.1.1, we need to use SSL_CTX_set_client_hello_cb()
126  * which is not in 1.1.0 instead of SSL_CTX_set_tlsext_servername_callback()
127  *
128  * However, there could be a runtime undefined external reference error
129  * as SSL_CTX_set_client_hello_cb() is not there in 1.1.0.
130  */
131  if (SSLeay() < 0x10101000L) {
132  coap_log(LOG_WARNING, "OpenSSL version 1.1.1 or later is required\n");
133  return 0;
134  }
135 #endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
136  return 1;
137 }
138 
139 int coap_tls_is_supported(void) {
140  if (SSLeay() < 0x10100000L) {
141  coap_log(LOG_WARNING, "OpenSSL version 1.1.0 or later is required\n");
142  return 0;
143  }
144 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
145  if (SSLeay() < 0x10101000L) {
146  coap_log(LOG_WARNING, "OpenSSL version 1.1.1 or later is required\n");
147  return 0;
148  }
149 #endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
150  return 1;
151 }
152 
155  static coap_tls_version_t version;
156  version.version = SSLeay();
157  version.built_version = OPENSSL_VERSION_NUMBER;
158  version.type = COAP_TLS_LIBRARY_OPENSSL;
159  return &version;
160 }
161 
162 void coap_dtls_startup(void) {
163  SSL_load_error_strings();
164  SSL_library_init();
165 }
166 
167 static int dtls_log_level = 0;
168 
169 void coap_dtls_set_log_level(int level) {
170  dtls_log_level = level;
171 }
172 
173 int coap_dtls_get_log_level(void) {
174  return dtls_log_level;
175 }
176 
177 typedef struct coap_ssl_st {
178  coap_session_t *session;
179  const void *pdu;
180  unsigned pdu_len;
181  unsigned peekmode;
182  coap_tick_t timeout;
183 } coap_ssl_data;
184 
185 static int coap_dgram_create(BIO *a) {
186  coap_ssl_data *data = NULL;
187  data = malloc(sizeof(coap_ssl_data));
188  if (data == NULL)
189  return 0;
190  BIO_set_init(a, 1);
191  BIO_set_data(a, data);
192  memset(data, 0x00, sizeof(coap_ssl_data));
193  return 1;
194 }
195 
196 static int coap_dgram_destroy(BIO *a) {
197  coap_ssl_data *data;
198  if (a == NULL)
199  return 0;
200  data = (coap_ssl_data *)BIO_get_data(a);
201  if (data != NULL)
202  free(data);
203  return 1;
204 }
205 
206 static int coap_dgram_read(BIO *a, char *out, int outl) {
207  int ret = 0;
208  coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
209 
210  if (out != NULL) {
211  if (data != NULL && data->pdu_len > 0) {
212  if (outl < (int)data->pdu_len) {
213  memcpy(out, data->pdu, outl);
214  ret = outl;
215  } else {
216  memcpy(out, data->pdu, data->pdu_len);
217  ret = (int)data->pdu_len;
218  }
219  if (!data->peekmode) {
220  data->pdu_len = 0;
221  data->pdu = NULL;
222  }
223  } else {
224  ret = -1;
225  }
226  BIO_clear_retry_flags(a);
227  if (ret < 0)
228  BIO_set_retry_read(a);
229  }
230  return ret;
231 }
232 
233 static int coap_dgram_write(BIO *a, const char *in, int inl) {
234  int ret = 0;
235  coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
236 
237  if (data->session) {
238  if (data->session->sock.flags == COAP_SOCKET_EMPTY && data->session->endpoint == NULL) {
239  /* socket was closed on client due to error */
240  BIO_clear_retry_flags(a);
241  return -1;
242  }
243  ret = (int)coap_session_send(data->session, (const uint8_t *)in, (size_t)inl);
244  BIO_clear_retry_flags(a);
245  if (ret <= 0)
246  BIO_set_retry_write(a);
247  } else {
248  BIO_clear_retry_flags(a);
249  ret = -1;
250  }
251  return ret;
252 }
253 
254 static int coap_dgram_puts(BIO *a, const char *pstr) {
255  return coap_dgram_write(a, pstr, (int)strlen(pstr));
256 }
257 
258 static long coap_dgram_ctrl(BIO *a, int cmd, long num, void *ptr) {
259  long ret = 1;
260  coap_ssl_data *data = BIO_get_data(a);
261 
262  (void)ptr;
263 
264  switch (cmd) {
265  case BIO_CTRL_GET_CLOSE:
266  ret = BIO_get_shutdown(a);
267  break;
268  case BIO_CTRL_SET_CLOSE:
269  BIO_set_shutdown(a, (int)num);
270  ret = 1;
271  break;
272  case BIO_CTRL_DGRAM_SET_PEEK_MODE:
273  data->peekmode = (unsigned)num;
274  break;
275  case BIO_CTRL_DGRAM_CONNECT:
276  case BIO_C_SET_FD:
277  case BIO_C_GET_FD:
278  case BIO_CTRL_DGRAM_SET_DONT_FRAG:
279  case BIO_CTRL_DGRAM_GET_MTU:
280  case BIO_CTRL_DGRAM_SET_MTU:
281  case BIO_CTRL_DGRAM_QUERY_MTU:
282  case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
283  ret = -1;
284  break;
285  case BIO_CTRL_DUP:
286  case BIO_CTRL_FLUSH:
287  case BIO_CTRL_DGRAM_MTU_DISCOVER:
288  case BIO_CTRL_DGRAM_SET_CONNECTED:
289  ret = 1;
290  break;
291  case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
292  data->timeout = coap_ticks_from_rt_us((uint64_t)((struct timeval*)ptr)->tv_sec * 1000000 + ((struct timeval*)ptr)->tv_usec);
293  ret = 1;
294  break;
295  case BIO_CTRL_RESET:
296  case BIO_C_FILE_SEEK:
297  case BIO_C_FILE_TELL:
298  case BIO_CTRL_INFO:
299  case BIO_CTRL_PENDING:
300  case BIO_CTRL_WPENDING:
301  case BIO_CTRL_DGRAM_GET_PEER:
302  case BIO_CTRL_DGRAM_SET_PEER:
303  case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
304  case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
305  case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
306  case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
307  case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
308  case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
309  case BIO_CTRL_DGRAM_MTU_EXCEEDED:
310  case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
311  default:
312  ret = 0;
313  break;
314  }
315  return ret;
316 }
317 
318 static int coap_dtls_generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) {
319  coap_dtls_context_t *dtls = (coap_dtls_context_t *)SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl));
320  coap_ssl_data *data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
321  int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
322  r &= HMAC_Update(dtls->cookie_hmac,
323  (const uint8_t*)&data->session->addr_info.local.addr,
324  (size_t)data->session->addr_info.local.size);
325  r &= HMAC_Update(dtls->cookie_hmac,
326  (const uint8_t*)&data->session->addr_info.remote.addr,
327  (size_t)data->session->addr_info.remote.size);
328  r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
329  return r;
330 }
331 
332 static int coap_dtls_verify_cookie(SSL *ssl, const uint8_t *cookie, unsigned int cookie_len) {
333  uint8_t hmac[32];
334  unsigned len = 32;
335  if (coap_dtls_generate_cookie(ssl, hmac, &len) && cookie_len == len && memcmp(cookie, hmac, len) == 0)
336  return 1;
337  else
338  return 0;
339 }
340 
341 static unsigned coap_dtls_psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *buf, unsigned max_len) {
342  size_t hint_len = 0, identity_len = 0, psk_len;
343  coap_session_t *session = (coap_session_t*)SSL_get_app_data(ssl);
344 
345  if (hint)
346  hint_len = strlen(hint);
347  else
348  hint = "";
349 
350  coap_log(LOG_DEBUG, "got psk_identity_hint: '%.*s'\n", (int)hint_len, hint);
351 
352  if (session == NULL || session->context == NULL || session->context->get_client_psk == NULL)
353  return 0;
354 
355  psk_len = session->context->get_client_psk(session, (const uint8_t*)hint, hint_len, (uint8_t*)identity, &identity_len, max_identity_len - 1, (uint8_t*)buf, max_len);
356  if (identity_len < max_identity_len)
357  identity[identity_len] = 0;
358  return (unsigned)psk_len;
359 }
360 
361 static unsigned coap_dtls_psk_server_callback(SSL *ssl, const char *identity, unsigned char *buf, unsigned max_len) {
362  size_t identity_len = 0;
363  coap_session_t *session = (coap_session_t*)SSL_get_app_data(ssl);
364 
365  if (identity)
366  identity_len = strlen(identity);
367  else
368  identity = "";
369 
370  coap_log(LOG_DEBUG, "got psk_identity: '%.*s'\n",
371  (int)identity_len, identity);
372 
373  if (session == NULL || session->context == NULL || session->context->get_server_psk == NULL)
374  return 0;
375 
376  return (unsigned)session->context->get_server_psk(session, (const uint8_t*)identity, identity_len, (uint8_t*)buf, max_len);
377 }
378 
379 static void coap_dtls_info_callback(const SSL *ssl, int where, int ret) {
380  coap_session_t *session = (coap_session_t*)SSL_get_app_data(ssl);
381  const char *pstr;
382  int w = where &~SSL_ST_MASK;
383 
384  if (w & SSL_ST_CONNECT)
385  pstr = "SSL_connect";
386  else if (w & SSL_ST_ACCEPT)
387  pstr = "SSL_accept";
388  else
389  pstr = "undefined";
390 
391  if (where & SSL_CB_LOOP) {
392  if (dtls_log_level >= LOG_DEBUG)
393  coap_log(LOG_DEBUG, "* %s: %s:%s\n",
394  coap_session_str(session), pstr, SSL_state_string_long(ssl));
395  } else if (where & SSL_CB_ALERT) {
396  pstr = (where & SSL_CB_READ) ? "read" : "write";
397  if (dtls_log_level >= LOG_INFO)
398  coap_log(LOG_INFO, "* %s: SSL3 alert %s:%s:%s\n",
399  coap_session_str(session),
400  pstr,
401  SSL_alert_type_string_long(ret),
402  SSL_alert_desc_string_long(ret));
403  if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL)
405  } else if (where & SSL_CB_EXIT) {
406  if (ret == 0) {
407  if (dtls_log_level >= LOG_WARNING) {
408  unsigned long e;
409  coap_log(LOG_WARNING, "* %s: %s:failed in %s\n",
410  coap_session_str(session), pstr, SSL_state_string_long(ssl));
411  while ((e = ERR_get_error()))
412  coap_log(LOG_WARNING, "* %s: %s at %s:%s\n",
413  coap_session_str(session), ERR_reason_error_string(e),
414  ERR_lib_error_string(e), ERR_func_error_string(e));
415  }
416  } else if (ret < 0) {
417  if (dtls_log_level >= LOG_WARNING) {
418  int err = SSL_get_error(ssl, ret);
419  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) {
420  long e;
421  coap_log(LOG_WARNING, "* %s: %s:error in %s\n",
422  coap_session_str(session), pstr, SSL_state_string_long(ssl));
423  while ((e = ERR_get_error()))
424  coap_log(LOG_WARNING, "* %s: %s at %s:%s\n",
425  coap_session_str(session), ERR_reason_error_string(e),
426  ERR_lib_error_string(e), ERR_func_error_string(e));
427  }
428  }
429  }
430  }
431 
432  if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
434 }
435 
436 static int coap_sock_create(BIO *a) {
437  BIO_set_init(a, 1);
438  return 1;
439 }
440 
441 static int coap_sock_destroy(BIO *a) {
442  (void)a;
443  return 1;
444 }
445 
446 static int coap_sock_read(BIO *a, char *out, int outl) {
447  int ret = 0;
448  coap_session_t *session = (coap_session_t *)BIO_get_data(a);
449 
450  if (out != NULL) {
451  ret = (int)coap_socket_read(&session->sock, (uint8_t*)out, (size_t)outl);
452  if (ret == 0) {
453  BIO_set_retry_read(a);
454  ret = -1;
455  } else {
456  BIO_clear_retry_flags(a);
457  }
458  }
459  return ret;
460 }
461 
462 static int coap_sock_write(BIO *a, const char *in, int inl) {
463  int ret = 0;
464  coap_session_t *session = (coap_session_t *)BIO_get_data(a);
465 
466  ret = (int)coap_socket_write(&session->sock, (const uint8_t*)in, (size_t)inl);
467  BIO_clear_retry_flags(a);
468  if (ret == 0) {
469  BIO_set_retry_read(a);
470  ret = -1;
471  } else {
472  BIO_clear_retry_flags(a);
473  }
474  return ret;
475 }
476 
477 static int coap_sock_puts(BIO *a, const char *pstr) {
478  return coap_sock_write(a, pstr, (int)strlen(pstr));
479 }
480 
481 static long coap_sock_ctrl(BIO *a, int cmd, long num, void *ptr) {
482  int r = 1;
483  (void)a;
484  (void)ptr;
485  (void)num;
486 
487  switch (cmd) {
488  case BIO_C_SET_FD:
489  case BIO_C_GET_FD:
490  r = -1;
491  break;
492  case BIO_CTRL_SET_CLOSE:
493  case BIO_CTRL_DUP:
494  case BIO_CTRL_FLUSH:
495  r = 1;
496  break;
497  default:
498  case BIO_CTRL_GET_CLOSE:
499  r = 0;
500  break;
501  }
502  return r;
503 }
504 
505 void *coap_dtls_new_context(struct coap_context_t *coap_context) {
506  coap_openssl_context_t *context;
507  (void)coap_context;
508 
509  context = (coap_openssl_context_t *)coap_malloc(sizeof(coap_openssl_context_t));
510  if (context) {
511  uint8_t cookie_secret[32];
512 
513  memset(context, 0, sizeof(coap_openssl_context_t));
514 
515  /* Set up DTLS context */
516  context->dtls.ctx = SSL_CTX_new(DTLS_method());
517  if (!context->dtls.ctx)
518  goto error;
519  SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
520  SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
521  SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
522  SSL_CTX_set_cipher_list(context->dtls.ctx, COAP_OPENSSL_CIPHERS);
523  memset(cookie_secret, 0, sizeof(cookie_secret));
524  if (!RAND_bytes(cookie_secret, (int)sizeof(cookie_secret))) {
527  "Insufficient entropy for random cookie generation");
528  prng(cookie_secret, sizeof(cookie_secret));
529  }
530  context->dtls.cookie_hmac = HMAC_CTX_new();
531  if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (int)sizeof(cookie_secret), EVP_sha256(), NULL))
532  goto error;
533  SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
534  SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
535  SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
536  SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
537  context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM, "coapdgram");
538  if (!context->dtls.meth)
539  goto error;
540  context->dtls.bio_addr = BIO_ADDR_new();
541  if (!context->dtls.bio_addr)
542  goto error;
543  BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
544  BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
545  BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
546  BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
547  BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
548  BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
549 
550  /* Set up TLS context */
551  context->tls.ctx = SSL_CTX_new(TLS_method());
552  if (!context->tls.ctx)
553  goto error;
554  SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
555  SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
556  SSL_CTX_set_cipher_list(context->tls.ctx, COAP_OPENSSL_CIPHERS);
557  SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
558  context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET, "coapsock");
559  if (!context->tls.meth)
560  goto error;
561  BIO_meth_set_write(context->tls.meth, coap_sock_write);
562  BIO_meth_set_read(context->tls.meth, coap_sock_read);
563  BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
564  BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
565  BIO_meth_set_create(context->tls.meth, coap_sock_create);
566  BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
567  }
568 
569  return context;
570 
571 error:
572  coap_dtls_free_context(context);
573  return NULL;
574 }
575 
576 int
578  const char *identity_hint,
579  coap_dtls_role_t role
580 ) {
581  coap_openssl_context_t *context = ((coap_openssl_context_t *)ctx->dtls_context);
582  BIO *bio;
583 
584  if (role == COAP_DTLS_ROLE_SERVER) {
585  SSL_CTX_set_psk_server_callback(context->dtls.ctx, coap_dtls_psk_server_callback);
586  SSL_CTX_set_psk_server_callback(context->tls.ctx, coap_dtls_psk_server_callback);
587  SSL_CTX_use_psk_identity_hint(context->dtls.ctx, identity_hint ? identity_hint : "");
588  SSL_CTX_use_psk_identity_hint(context->tls.ctx, identity_hint ? identity_hint : "");
589  }
590  if (!context->dtls.ssl) {
591  /* This is set up to handle new incoming sessions to a server */
592  context->dtls.ssl = SSL_new(context->dtls.ctx);
593  if (!context->dtls.ssl)
594  return 0;
595  bio = BIO_new(context->dtls.meth);
596  if (!bio) {
597  SSL_free (context->dtls.ssl);
598  context->dtls.ssl = NULL;
599  return 0;
600  }
601  SSL_set_bio(context->dtls.ssl, bio, bio);
602  SSL_set_app_data(context->dtls.ssl, NULL);
603  SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
604  SSL_set_mtu(context->dtls.ssl, COAP_DEFAULT_MTU);
605  }
606  context->psk_pki_enabled |= IS_PSK;
607  return 1;
608 }
609 
610 static int
611 map_key_type(int asn1_private_key_type
612 ) {
613  switch (asn1_private_key_type) {
614  case COAP_ASN1_PKEY_NONE: return EVP_PKEY_NONE;
615  case COAP_ASN1_PKEY_RSA: return EVP_PKEY_RSA;
616  case COAP_ASN1_PKEY_RSA2: return EVP_PKEY_RSA2;
617  case COAP_ASN1_PKEY_DSA: return EVP_PKEY_DSA;
618  case COAP_ASN1_PKEY_DSA1: return EVP_PKEY_DSA1;
619  case COAP_ASN1_PKEY_DSA2: return EVP_PKEY_DSA2;
620  case COAP_ASN1_PKEY_DSA3: return EVP_PKEY_DSA3;
621  case COAP_ASN1_PKEY_DSA4: return EVP_PKEY_DSA4;
622  case COAP_ASN1_PKEY_DH: return EVP_PKEY_DH;
623  case COAP_ASN1_PKEY_DHX: return EVP_PKEY_DHX;
624  case COAP_ASN1_PKEY_EC: return EVP_PKEY_EC;
625  case COAP_ASN1_PKEY_HMAC: return EVP_PKEY_HMAC;
626  case COAP_ASN1_PKEY_CMAC: return EVP_PKEY_CMAC;
627  case COAP_ASN1_PKEY_TLS1_PRF: return EVP_PKEY_TLS1_PRF;
628  case COAP_ASN1_PKEY_HKDF: return EVP_PKEY_HKDF;
629  default:
631  "*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
632  asn1_private_key_type);
633  break;
634  }
635  return 0;
636 }
637 static uint8_t coap_alpn[] = { 4, 'c', 'o', 'a', 'p' };
638 
639 static int
640 server_alpn_callback (SSL *ssl UNUSED,
641  const unsigned char **out,
642  unsigned char *outlen,
643  const unsigned char *in,
644  unsigned int inlen,
645  void *arg UNUSED
646 ) {
647  unsigned char *tout = NULL;
648  int ret;
649  if (inlen == 0)
650  return SSL_TLSEXT_ERR_NOACK;
651  ret = SSL_select_next_proto(&tout,
652  outlen,
653  coap_alpn,
654  sizeof(coap_alpn),
655  in,
656  inlen);
657  *out = tout;
658  return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
659 }
660 
661 static void
662 add_ca_to_cert_store(X509_STORE *st, X509 *x509)
663 {
664  long e;
665 
666  /* Flush out existing errors */
667  while ((e = ERR_get_error()) != 0) {
668  }
669 
670  if (!X509_STORE_add_cert(st, x509)) {
671  while ((e = ERR_get_error()) != 0) {
672  int r = ERR_GET_REASON(e);
673  if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
674  /* Not already added */
675  coap_log(LOG_WARNING, "***setup_pki: (D)TLS: %s at %s:%s\n",
676  ERR_reason_error_string(e),
677  ERR_lib_error_string(e),
678  ERR_func_error_string(e));
679  }
680  }
681  }
682 }
683 
684 #if OPENSSL_VERSION_NUMBER < 0x10101000L
685 static int
686 setup_pki_server(SSL_CTX *ctx,
687  coap_dtls_pki_t* setup_data
688 ) {
689  switch (setup_data->pki_key.key_type) {
690  case COAP_PKI_KEY_PEM:
691  if (setup_data->pki_key.key.pem.public_cert &&
692  setup_data->pki_key.key.pem.public_cert[0]) {
693  if (!(SSL_CTX_use_certificate_file(ctx,
694  setup_data->pki_key.key.pem.public_cert,
695  SSL_FILETYPE_PEM))) {
697  "*** setup_pki: (D)TLS: %s: Unable to configure "
698  "Server Certificate\n",
699  setup_data->pki_key.key.pem.public_cert);
700  return 0;
701  }
702  }
703  else {
705  "*** setup_pki: (D)TLS: No Server Certificate defined\n");
706  return 0;
707  }
708 
709  if (setup_data->pki_key.key.pem.private_key &&
710  setup_data->pki_key.key.pem.private_key[0]) {
711  if (!(SSL_CTX_use_PrivateKey_file(ctx,
712  setup_data->pki_key.key.pem.private_key,
713  SSL_FILETYPE_PEM))) {
715  "*** setup_pki: (D)TLS: %s: Unable to configure "
716  "Server Private Key\n",
717  setup_data->pki_key.key.pem.private_key);
718  return 0;
719  }
720  }
721  else {
723  "*** setup_pki: (D)TLS: No Server Private Key defined\n");
724  return 0;
725  }
726 
727  if (setup_data->pki_key.key.pem.ca_file &&
728  setup_data->pki_key.key.pem.ca_file[0]) {
729  STACK_OF(X509_NAME) *cert_names;
730  X509_STORE *st;
731  BIO *in;
732  X509 *x = NULL;
733  char *rw_var = NULL;
734  cert_names = SSL_load_client_CA_file(setup_data->pki_key.key.pem.ca_file);
735  if (cert_names != NULL)
736  SSL_CTX_set_client_CA_list(ctx, cert_names);
737  else {
739  "*** setup_pki: (D)TLS: %s: Unable to configure "
740  "client CA File\n",
741  setup_data->pki_key.key.pem.ca_file);
742  return 0;
743  }
744  st = SSL_CTX_get_cert_store(ctx);
745  in = BIO_new(BIO_s_file());
746  /* Need to do this to not get a compiler warning about const parameters */
747  memcpy(&rw_var, &setup_data->pki_key.key.pem.ca_file, sizeof (rw_var));
748  if (!BIO_read_filename(in, rw_var)) {
749  BIO_free(in);
750  X509_free(x);
751  break;
752  }
753 
754  for (;;) {
755  if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
756  break;
757  add_ca_to_cert_store(st, x);
758  }
759  BIO_free(in);
760  X509_free(x);
761  }
762  break;
763 
764  case COAP_PKI_KEY_ASN1:
765  if (setup_data->pki_key.key.asn1.public_cert &&
766  setup_data->pki_key.key.asn1.public_cert_len > 0) {
767  if (!(SSL_CTX_use_certificate_ASN1(ctx,
768  setup_data->pki_key.key.asn1.public_cert_len,
769  setup_data->pki_key.key.asn1.public_cert))) {
771  "*** setup_pki: (D)TLS: %s: Unable to configure "
772  "Server Certificate\n",
773  "ASN1");
774  return 0;
775  }
776  }
777  else {
779  "*** setup_pki: (D)TLS: No Server Certificate defined\n");
780  return 0;
781  }
782 
783  if (setup_data->pki_key.key.asn1.private_key &&
784  setup_data->pki_key.key.asn1.private_key_len > 0) {
785  int pkey_type = map_key_type(setup_data->pki_key.key.asn1.private_key_type);
786  if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx,
787  setup_data->pki_key.key.asn1.private_key,
788  setup_data->pki_key.key.asn1.private_key_len))) {
790  "*** setup_pki: (D)TLS: %s: Unable to configure "
791  "Server Private Key\n",
792  "ASN1");
793  return 0;
794  }
795  }
796  else {
798  "*** setup_pki: (D)TLS: No Server Private Key defined\n");
799  return 0;
800  }
801 
802  if (setup_data->pki_key.key.asn1.ca_cert &&
803  setup_data->pki_key.key.asn1.ca_cert_len > 0) {
804  /* Need to use a temp variable as it gets incremented*/
805  const uint8_t *p = setup_data->pki_key.key.asn1.ca_cert;
806  X509* x509 = d2i_X509(NULL, &p, setup_data->pki_key.key.asn1.ca_cert_len);
807  X509_STORE *st;
808  if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
810  "*** setup_pki: (D)TLS: %s: Unable to configure "
811  "client CA File\n",
812  "ASN1");
813  X509_free(x509);
814  return 0;
815  }
816  st = SSL_CTX_get_cert_store(ctx);
817  add_ca_to_cert_store(st, x509);
818  X509_free(x509);
819  }
820  break;
821  default:
823  "*** setup_pki: (D)TLS: Unknown key type %d\n",
824  setup_data->pki_key.key_type);
825  return 0;
826  }
827 
828  return 1;
829 }
830 #endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
831 
832 static int
833 setup_pki_ssl(SSL *ssl,
834  coap_dtls_pki_t* setup_data, coap_dtls_role_t role
835 ) {
836  switch (setup_data->pki_key.key_type) {
837  case COAP_PKI_KEY_PEM:
838  if (setup_data->pki_key.key.pem.public_cert &&
839  setup_data->pki_key.key.pem.public_cert[0]) {
840  if (!(SSL_use_certificate_file(ssl,
841  setup_data->pki_key.key.pem.public_cert,
842  SSL_FILETYPE_PEM))) {
844  "*** setup_pki: (D)TLS: %s: Unable to configure "
845  "%s Certificate\n",
846  setup_data->pki_key.key.pem.public_cert,
847  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
848  return 0;
849  }
850  }
851  else if (role == COAP_DTLS_ROLE_SERVER ||
852  (setup_data->pki_key.key.pem.private_key &&
853  setup_data->pki_key.key.pem.private_key[0])) {
855  "*** setup_pki: (D)TLS: No %s Certificate defined\n",
856  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
857  return 0;
858  }
859  if (setup_data->pki_key.key.pem.private_key &&
860  setup_data->pki_key.key.pem.private_key[0]) {
861  if (!(SSL_use_PrivateKey_file(ssl,
862  setup_data->pki_key.key.pem.private_key,
863  SSL_FILETYPE_PEM))) {
865  "*** setup_pki: (D)TLS: %s: Unable to configure "
866  "Client Private Key\n",
867  setup_data->pki_key.key.pem.private_key);
868  return 0;
869  }
870  }
871  else if (role == COAP_DTLS_ROLE_SERVER ||
872  (setup_data->pki_key.key.pem.public_cert &&
873  setup_data->pki_key.key.pem.public_cert[0])) {
875  "*** setup_pki: (D)TLS: No %s Private Key defined\n",
876  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
877  return 0;
878  }
879  if (setup_data->pki_key.key.pem.ca_file &&
880  setup_data->pki_key.key.pem.ca_file[0]) {
881  X509_STORE *st;
882  BIO *in;
883  X509 *x = NULL;
884  char *rw_var = NULL;
885  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
886 
887  if (role == COAP_DTLS_ROLE_SERVER) {
888  STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(setup_data->pki_key.key.pem.ca_file);
889 
890  if (cert_names != NULL)
891  SSL_set_client_CA_list(ssl, cert_names);
892  else {
894  "*** setup_pki: (D)TLS: %s: Unable to configure "
895  "%s CA File\n",
896  setup_data->pki_key.key.pem.ca_file,
897  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
898  return 0;
899  }
900  }
901 
902  /* Add CA to the trusted root CA store */
903  in = BIO_new(BIO_s_file());
904  /* Need to do this to not get a compiler warning about const parameters */
905  memcpy(&rw_var, &setup_data->pki_key.key.pem.ca_file, sizeof (rw_var));
906  if (!BIO_read_filename(in, rw_var)) {
907  BIO_free(in);
908  X509_free(x);
909  break;
910  }
911  st = SSL_CTX_get_cert_store(ctx);
912  for (;;) {
913  if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
914  break;
915  add_ca_to_cert_store(st, x);
916  }
917  BIO_free(in);
918  X509_free(x);
919  }
920  break;
921 
922  case COAP_PKI_KEY_ASN1:
923  if (setup_data->pki_key.key.asn1.public_cert &&
924  setup_data->pki_key.key.asn1.public_cert_len > 0) {
925  if (!(SSL_use_certificate_ASN1(ssl,
926  setup_data->pki_key.key.asn1.public_cert,
927  setup_data->pki_key.key.asn1.public_cert_len))) {
929  "*** setup_pki: (D)TLS: %s: Unable to configure "
930  "%s Certificate\n",
931  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client",
932  "ASN1");
933  return 0;
934  }
935  }
936  else if (role == COAP_DTLS_ROLE_SERVER ||
937  (setup_data->pki_key.key.asn1.private_key &&
938  setup_data->pki_key.key.asn1.private_key[0])) {
940  "*** setup_pki: (D)TLS: No %s Certificate defined\n",
941  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
942  return 0;
943  }
944  if (setup_data->pki_key.key.asn1.private_key &&
945  setup_data->pki_key.key.asn1.private_key_len > 0) {
946  int pkey_type = map_key_type(setup_data->pki_key.key.asn1.private_key_type);
947  if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
948  setup_data->pki_key.key.asn1.private_key,
949  setup_data->pki_key.key.asn1.private_key_len))) {
951  "*** setup_pki: (D)TLS: %s: Unable to configure "
952  "%s Private Key\n",
953  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client",
954  "ASN1");
955  return 0;
956  }
957  }
958  else if (role == COAP_DTLS_ROLE_SERVER ||
959  (setup_data->pki_key.key.asn1.public_cert &&
960  setup_data->pki_key.key.asn1.public_cert_len > 0)) {
962  "*** setup_pki: (D)TLS: No %s Private Key defined",
963  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
964  return 0;
965  }
966  if (setup_data->pki_key.key.asn1.ca_cert &&
967  setup_data->pki_key.key.asn1.ca_cert_len > 0) {
968  /* Need to use a temp variable as it gets incremented*/
969  const uint8_t *p = setup_data->pki_key.key.asn1.ca_cert;
970  X509* x509 = d2i_X509(NULL, &p, setup_data->pki_key.key.asn1.ca_cert_len);
971  X509_STORE *st;
972  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
973 
974  if (role == COAP_DTLS_ROLE_SERVER) {
975  if (!x509 || !SSL_add_client_CA(ssl, x509)) {
977  "*** setup_pki: (D)TLS: %s: Unable to configure "
978  "client CA File\n",
979  "ASN1");
980  X509_free(x509);
981  return 0;
982  }
983  }
984 
985  /* Add CA to the trusted root CA store */
986  st = SSL_CTX_get_cert_store(ctx);
987  add_ca_to_cert_store(st, x509);
988  X509_free(x509);
989  }
990  break;
991  default:
993  "*** setup_pki: (D)TLS: Unknown key type %d\n",
994  setup_data->pki_key.key_type);
995  return 0;
996  }
997  return 1;
998 }
999 
1000 static char*
1001 get_san_or_cn_from_cert(X509* x509) {
1002  if (x509) {
1003  char *cn;
1004  int n;
1005  STACK_OF(GENERAL_NAME) *san_list;
1006  char buffer[256];
1007 
1008  san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
1009  if (san_list) {
1010  int san_count = sk_GENERAL_NAME_num(san_list);
1011 
1012  for (n = 0; n < san_count; n++) {
1013  const GENERAL_NAME * name = sk_GENERAL_NAME_value (san_list, n);
1014 
1015  if (name->type == GEN_DNS) {
1016  const char *dns_name = (const char *)ASN1_STRING_get0_data(name->d.dNSName);
1017 
1018  /* Make sure that there is not an embedded NUL in the dns_name */
1019  if (ASN1_STRING_length(name->d.dNSName) != (int)strlen (dns_name))
1020  continue;
1021  cn = OPENSSL_strdup(dns_name);
1022  sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1023  return cn;
1024  }
1025  }
1026  sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1027  }
1028  /* Otherwise look for the CN= field */
1029  X509_NAME_oneline(X509_get_subject_name(x509), buffer, sizeof(buffer));
1030 
1031  /* Need to emulate strcasestr() here. Looking for CN= */
1032  n = strlen(buffer) - 3;
1033  cn = buffer;
1034  while (n > 0) {
1035  if (((cn[0] == 'C') || (cn[0] == 'c')) &&
1036  ((cn[1] == 'N') || (cn[1] == 'n')) &&
1037  (cn[2] == '=')) {
1038  cn += 3;
1039  break;
1040  }
1041  cn++;
1042  n--;
1043  }
1044  if (n > 0) {
1045  char * ecn = strchr(cn, '/');
1046  if (ecn) {
1047  return OPENSSL_strndup(cn, ecn-cn);
1048  }
1049  else {
1050  return OPENSSL_strdup(cn);
1051  }
1052  }
1053  }
1054  return NULL;
1055 }
1056 
1057 static int
1058 tls_verify_call_back(int preverify_ok, X509_STORE_CTX *ctx) {
1059  SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
1060  SSL_get_ex_data_X509_STORE_CTX_idx());
1061  coap_session_t *session = SSL_get_app_data(ssl);
1062  coap_openssl_context_t *context =
1063  ((coap_openssl_context_t *)session->context->dtls_context);
1064  coap_dtls_pki_t *setup_data = &context->setup_data;
1065  int depth = X509_STORE_CTX_get_error_depth(ctx);
1066  int err = X509_STORE_CTX_get_error(ctx);
1067  X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1068  char *cn = get_san_or_cn_from_cert(x509);
1069  int keep_preverify_ok = preverify_ok;
1070 
1071  if (!preverify_ok) {
1072  switch (err) {
1073  case X509_V_ERR_CERT_NOT_YET_VALID:
1074  case X509_V_ERR_CERT_HAS_EXPIRED:
1075  if (setup_data->allow_expired_certs)
1076  preverify_ok = 1;
1077  break;
1078  case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1079  if (setup_data->allow_self_signed)
1080  preverify_ok = 1;
1081  break;
1082  case X509_V_ERR_UNABLE_TO_GET_CRL:
1083  if (setup_data->allow_no_crl)
1084  preverify_ok = 1;
1085  break;
1086  case X509_V_ERR_CRL_NOT_YET_VALID:
1087  case X509_V_ERR_CRL_HAS_EXPIRED:
1088  if (setup_data->allow_expired_crl)
1089  preverify_ok = 1;
1090  break;
1091  default:
1092  break;
1093  }
1094  if (!preverify_ok) {
1096  " %s: %s: '%s' depth=%d\n",
1097  coap_session_str(session),
1098  X509_verify_cert_error_string(err), cn ? cn : "?", depth);
1099  /* Invoke the CN callback function for this failure */
1100  keep_preverify_ok = 1;
1101  }
1102  else {
1104  " %s: %s: overridden: '%s' depth=%d\n",
1105  coap_session_str(session),
1106  X509_verify_cert_error_string(err), cn ? cn : "?", depth);
1107  }
1108  }
1109  /* Certificate - depth == 0 is the Client Cert */
1110  if (setup_data->validate_cn_call_back && keep_preverify_ok) {
1111  int length = i2d_X509(x509, NULL);
1112  uint8_t *base_buf;
1113  uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
1114 
1115  /* base_buf2 gets moved to the end */
1116  i2d_X509(x509, &base_buf2);
1117  if (!setup_data->validate_cn_call_back(cn, base_buf, length, session,
1118  depth, preverify_ok,
1119  setup_data->cn_call_back_arg)) {
1120  if (depth == 0) {
1121  X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1122  }
1123  else {
1124  X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1125  }
1126  preverify_ok = 0;
1127  }
1128  OPENSSL_free(base_buf);
1129  }
1130  OPENSSL_free(cn);
1131  return preverify_ok;
1132 }
1133 
1134 #if OPENSSL_VERSION_NUMBER < 0x10101000L
1135 /*
1136  * During the SSL/TLS initial negotiations, tls_secret_call_back() is called so
1137  * it is possible to determine whether this is a PKI or PSK incoming
1138  * request and adjust the ciphers if necessary
1139  *
1140  * Set up by SSL_set_session_secret_cb() in tls_server_name_call_back()
1141  */
1142 static int
1143 tls_secret_call_back(SSL *ssl,
1144  void *secret UNUSED,
1145  int *secretlen UNUSED,
1146  STACK_OF(SSL_CIPHER) *peer_ciphers,
1147  const SSL_CIPHER **cipher UNUSED,
1148  void *arg
1149 ) {
1150  int ii;
1151  int psk_requested = 0;
1152  coap_session_t *session = SSL_get_app_data(ssl);
1153  coap_dtls_pki_t *setup_data = (coap_dtls_pki_t*)arg;
1154 
1155  if (session && session->context->psk_key && session->context->psk_key_len) {
1156  /* Is PSK being requested - if so, we need to change algorithms */
1157  for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1158  const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1159 
1160  coap_log(COAP_LOG_CIPHERS, "Client cipher: %s\n",
1161  SSL_CIPHER_get_name(peer_cipher));
1162  if (strstr (SSL_CIPHER_get_name (peer_cipher), "PSK")) {
1163  psk_requested = 1;
1164  break;
1165  }
1166  }
1167  }
1168  if (!psk_requested) {
1169  if (session) {
1170  coap_log(LOG_DEBUG, " %s: Using PKI ciphers\n",
1171  coap_session_str(session));
1172  }
1173  else {
1174  coap_log(LOG_DEBUG, "Using PKI ciphers\n");
1175  }
1176  if (setup_data->verify_peer_cert) {
1177  if (setup_data->require_peer_cert) {
1178  SSL_set_verify(ssl,
1179  SSL_VERIFY_PEER |
1180  SSL_VERIFY_CLIENT_ONCE |
1181  SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1182  tls_verify_call_back);
1183  }
1184  else {
1185  SSL_set_verify(ssl,
1186  SSL_VERIFY_PEER |
1187  SSL_VERIFY_CLIENT_ONCE,
1188  tls_verify_call_back);
1189  }
1190  }
1191  else {
1192  SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1193  }
1194 
1195  /* Check CA Chain */
1196  if (setup_data->cert_chain_validation)
1197  SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth);
1198 
1199  /* Certificate Revocation */
1200  if (setup_data->check_cert_revocation) {
1201  X509_VERIFY_PARAM *param;
1202 
1203  param = X509_VERIFY_PARAM_new();
1204  X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1205  SSL_set1_param(ssl, param);
1206  X509_VERIFY_PARAM_free(param);
1207  }
1208  }
1209  else {
1210  if (session) {
1211  if (session->context->psk_key && session->context->psk_key_len) {
1212  memcpy(secret, session->context->psk_key, session->context->psk_key_len);
1213  *secretlen = session->context->psk_key_len;
1214  }
1215  coap_log(LOG_DEBUG, " %s: Setting PSK ciphers\n",
1216  coap_session_str(session));
1217  }
1218  else {
1219  coap_log(LOG_DEBUG, "Setting PSK ciphers\n");
1220  }
1221  /*
1222  * Force a PSK algorithm to be used, so we do PSK
1223  */
1224  SSL_set_cipher_list (ssl, COAP_OPENSSL_PSK_CIPHERS);
1225  SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1226  }
1227  if (setup_data->additional_tls_setup_call_back) {
1228  /* Additional application setup wanted */
1229  if (!setup_data->additional_tls_setup_call_back(ssl, setup_data))
1230  return 0;
1231  }
1232  return 0;
1233 }
1234 
1235 /*
1236  * During the SSL/TLS initial negotiations, tls_server_name_call_back() is called
1237  * so it is possible to set up an extra callback to determine whether this is
1238  * a PKI or PSK incoming request and adjust the ciphers if necessary
1239  *
1240  * Set up by SSL_CTX_set_tlsext_servername_callback() in coap_dtls_context_set_pki()
1241  */
1242 static int
1243 tls_server_name_call_back(SSL *ssl,
1244  int *sd UNUSED,
1245  void *arg
1246 ) {
1247  coap_dtls_pki_t *setup_data = (coap_dtls_pki_t*)arg;
1248 
1249  if (!ssl) {
1250  return SSL_TLSEXT_ERR_NOACK;
1251  }
1252 
1253  if (setup_data->validate_sni_call_back) {
1254  /* SNI checking requested */
1255  coap_session_t *session = (coap_session_t*)SSL_get_app_data(ssl);
1256  coap_openssl_context_t *context =
1257  ((coap_openssl_context_t *)session->context->dtls_context);
1258  const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1259  size_t i;
1260 
1261  if (!sni || !sni[0]) {
1262  sni = "";
1263  }
1264  for (i = 0; i < context->sni_count; i++) {
1265  if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1266  break;
1267  }
1268  }
1269  if (i == context->sni_count) {
1270  SSL_CTX *ctx;
1271  coap_dtls_pki_t sni_setup_data;
1272  coap_dtls_key_t *new_entry = setup_data->validate_sni_call_back(sni,
1273  setup_data->sni_call_back_arg);
1274  if (!new_entry) {
1275  return SSL_TLSEXT_ERR_ALERT_FATAL;
1276  }
1277  /* Need to set up a new SSL_CTX to switch to */
1278  if (session->proto == COAP_PROTO_DTLS) {
1279  /* Set up DTLS context */
1280  ctx = SSL_CTX_new(DTLS_method());
1281  if (!ctx)
1282  goto error;
1283  SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
1284  SSL_CTX_set_app_data(ctx, &context->dtls);
1285  SSL_CTX_set_read_ahead(ctx, 1);
1286  SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
1287  SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
1288  SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
1289  SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1290  SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
1291  }
1292  else {
1293  /* Set up TLS context */
1294  ctx = SSL_CTX_new(TLS_method());
1295  if (!ctx)
1296  goto error;
1297  SSL_CTX_set_app_data(ctx, &context->tls);
1298  SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1299  SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
1300  SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1301  SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
1302  }
1303  memset(&sni_setup_data, 0, sizeof(sni_setup_data));
1304  sni_setup_data.pki_key.key_type = new_entry->key_type;
1305  sni_setup_data.pki_key.key.pem = new_entry->key.pem;
1306  sni_setup_data.pki_key.key.asn1 = new_entry->key.asn1;
1307  setup_pki_server(ctx, &sni_setup_data);
1308 
1309  context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1310  (context->sni_count+1)*sizeof(sni_entry));
1311  context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1312  context->sni_entry_list[context->sni_count].ctx = ctx;
1313  context->sni_count++;
1314  }
1315  SSL_set_SSL_CTX (ssl, context->sni_entry_list[i].ctx);
1316  SSL_clear_options (ssl, 0xFFFFFFFFL);
1317  SSL_set_options (ssl, SSL_CTX_get_options (context->sni_entry_list[i].ctx));
1318  }
1319 
1320  /*
1321  * Have to do extra call back next to get client algorithms
1322  * SSL_get_client_ciphers() does not work this early on
1323  */
1324  SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
1325  return SSL_TLSEXT_ERR_OK;
1326 
1327 error:
1328  return SSL_TLSEXT_ERR_ALERT_WARNING;
1329 }
1330 #else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1331 /*
1332  * During the SSL/TLS initial negotiations, tls_client_hello_call_back() is
1333  * called early in the Client Hello processing so it is possible to determine
1334  * whether this is a PKI or PSK incoming request and adjust the ciphers if
1335  * necessary.
1336  *
1337  * Set up by SSL_CTX_set_client_hello_cb().
1338  */
1339 static int
1340 tls_client_hello_call_back(SSL *ssl,
1341  int *al,
1342  void *arg UNUSED
1343 ) {
1344  coap_session_t *session;
1345  coap_openssl_context_t *dtls_context;
1346  coap_dtls_pki_t *setup_data;
1347  int psk_requested = 0;
1348  const unsigned char *out;
1349  size_t outlen;
1350 
1351  if (!ssl) {
1352  *al = SSL_AD_INTERNAL_ERROR;
1353  return SSL_CLIENT_HELLO_ERROR;
1354  }
1355  session = (coap_session_t *)SSL_get_app_data(ssl);
1356  assert(session != NULL);
1357  assert(session->context != NULL);
1358  assert(session->context->dtls_context != NULL);
1359  dtls_context = (coap_openssl_context_t *)session->context->dtls_context;
1360  setup_data = &dtls_context->setup_data;
1361 
1362  /*
1363  * See if PSK being requested
1364  */
1365  if (session->context->psk_key && session->context->psk_key_len) {
1366  int len = SSL_client_hello_get0_ciphers(ssl, &out);
1367  STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
1368  STACK_OF(SSL_CIPHER) *scsvc = NULL;
1369 
1370  if (len && SSL_bytes_to_cipher_list(ssl, out, len,
1371  SSL_client_hello_isv2(ssl),
1372  &peer_ciphers, &scsvc)) {
1373  int ii;
1374  for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1375  const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1376 
1377  coap_log(COAP_LOG_CIPHERS, "Client cipher: %s (%04x)\n",
1378  SSL_CIPHER_get_name(peer_cipher),
1379  SSL_CIPHER_get_protocol_id(peer_cipher));
1380  if (strstr (SSL_CIPHER_get_name (peer_cipher), "PSK")) {
1381  psk_requested = 1;
1382  break;
1383  }
1384  }
1385  }
1386  sk_SSL_CIPHER_free(peer_ciphers);
1387  sk_SSL_CIPHER_free(scsvc);
1388  }
1389 
1390  if (psk_requested) {
1391  /*
1392  * Client has requested PSK and it is supported
1393  */
1394  if (session) {
1395  coap_log(LOG_DEBUG, " %s: PSK request\n",
1396  coap_session_str(session));
1397  }
1398  else {
1399  coap_log(LOG_DEBUG, "PSK request\n");
1400  }
1401  SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1402  if (setup_data->additional_tls_setup_call_back) {
1403  /* Additional application setup wanted */
1404  if (!setup_data->additional_tls_setup_call_back(ssl, setup_data))
1405  return 0;
1406  }
1407  return SSL_CLIENT_HELLO_SUCCESS;
1408  }
1409 
1410  /*
1411  * Handle Certificate requests
1412  */
1413 
1414  /*
1415  * Determine what type of certificate is being requested
1416  */
1417  if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
1418  &out, &outlen)) {
1419  size_t ii;
1420  for (ii = 0; ii < outlen; ii++) {
1421  switch (out[ii]) {
1422  case 0:
1423  /* RFC6091 X.509 */
1424  if (outlen >= 2) {
1425  /* X.509 cannot be the singular entry. RFC6091 3.1. Client Hello */
1426  goto is_x509;
1427  }
1428  break;
1429  case 2:
1430  /* RFC7250 RPK - not yet supported */
1431  break;
1432  default:
1433  break;
1434  }
1435  }
1436  *al = SSL_AD_UNSUPPORTED_EXTENSION;
1437  return SSL_CLIENT_HELLO_ERROR;
1438  }
1439 
1440 is_x509:
1441  if (setup_data->validate_sni_call_back) {
1442  /*
1443  * SNI checking requested
1444  */
1445  coap_dtls_pki_t sni_setup_data;
1446  coap_openssl_context_t *context =
1447  ((coap_openssl_context_t *)session->context->dtls_context);
1448  const char *sni = "";
1449  char *sni_tmp = NULL;
1450  size_t i;
1451 
1452  if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
1453  outlen > 5 &&
1454  (((out[0]<<8) + out[1] +2) == (int)outlen) &&
1455  out[2] == TLSEXT_NAMETYPE_host_name &&
1456  (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
1457  /* Skip over length, type and length */
1458  out += 5;
1459  outlen -= 5;
1460  sni_tmp = OPENSSL_malloc(outlen+1);
1461  sni_tmp[outlen] = '\000';
1462  memcpy(sni_tmp, out, outlen);
1463  sni = sni_tmp;
1464  }
1465  /* Is this a cached entry? */
1466  for (i = 0; i < context->sni_count; i++) {
1467  if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1468  break;
1469  }
1470  }
1471  if (i == context->sni_count) {
1472  /*
1473  * New SNI request
1474  */
1475  coap_dtls_key_t *new_entry = setup_data->validate_sni_call_back(sni,
1476  setup_data->sni_call_back_arg);
1477  if (!new_entry) {
1478  *al = SSL_AD_UNRECOGNIZED_NAME;
1479  return SSL_CLIENT_HELLO_ERROR;
1480  }
1481 
1482 
1483  context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1484  (context->sni_count+1)*sizeof(sni_entry));
1485  context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1486  context->sni_entry_list[context->sni_count].pki_key = *new_entry;
1487  context->sni_count++;
1488  }
1489  if (sni_tmp) {
1490  OPENSSL_free(sni_tmp);
1491  }
1492  memset(&sni_setup_data, 0, sizeof(sni_setup_data));
1493  sni_setup_data.pki_key = context->sni_entry_list[i].pki_key;
1494  setup_pki_ssl(ssl, &sni_setup_data, 1);
1495  }
1496  else {
1497  setup_pki_ssl(ssl, setup_data, 1);
1498  }
1499 
1500  if (session) {
1501  coap_log(LOG_DEBUG, " %s: Using PKI ciphers\n",
1502  coap_session_str(session));
1503  }
1504  else {
1505  coap_log(LOG_DEBUG, "Using PKI ciphers\n");
1506  }
1507  if (setup_data->verify_peer_cert) {
1508  if (setup_data->require_peer_cert) {
1509  SSL_set_verify(ssl,
1510  SSL_VERIFY_PEER |
1511  SSL_VERIFY_CLIENT_ONCE |
1512  SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1513  tls_verify_call_back);
1514  }
1515  else {
1516  SSL_set_verify(ssl,
1517  SSL_VERIFY_PEER |
1518  SSL_VERIFY_CLIENT_ONCE,
1519  tls_verify_call_back);
1520  }
1521  }
1522  else {
1523  SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1524  }
1525 
1526  /* Check CA Chain */
1527  if (setup_data->cert_chain_validation)
1528  SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth);
1529 
1530  /* Certificate Revocation */
1531  if (setup_data->check_cert_revocation) {
1532  X509_VERIFY_PARAM *param;
1533 
1534  param = X509_VERIFY_PARAM_new();
1535  X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1536  SSL_set1_param(ssl, param);
1537  X509_VERIFY_PARAM_free(param);
1538  }
1539  if (setup_data->additional_tls_setup_call_back) {
1540  /* Additional application setup wanted */
1541  if (!setup_data->additional_tls_setup_call_back(ssl, setup_data))
1542  return 0;
1543  }
1544  return SSL_CLIENT_HELLO_SUCCESS;
1545 }
1546 #endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1547 
1548 int
1550  coap_dtls_pki_t *setup_data,
1551  coap_dtls_role_t role
1552 ) {
1553  coap_openssl_context_t *context =
1554  ((coap_openssl_context_t *)ctx->dtls_context);
1555  BIO *bio;
1556  if (!setup_data)
1557  return 0;
1558  context->setup_data = *setup_data;
1559  if (role == COAP_DTLS_ROLE_SERVER) {
1560  if (context->dtls.ctx) {
1561  /* SERVER DTLS */
1562 #if OPENSSL_VERSION_NUMBER < 0x10101000L
1563  if (!setup_pki_server(context->dtls.ctx, setup_data))
1564  return 0;
1565 #endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
1566  /* libcoap is managing TLS connection based on setup_data options */
1567  /* Need to set up logic to differentiate between a PSK or PKI session */
1568  /*
1569  * For OpenSSL 1.1.1, we need to use SSL_CTX_set_client_hello_cb()
1570  * which is not in 1.1.0
1571  */
1572 #if OPENSSL_VERSION_NUMBER < 0x10101000L
1573  if (SSLeay() >= 0x10101000L) {
1575  "OpenSSL compiled with %lux, linked with %lux, so "
1576  "no certificate checking\n",
1577  OPENSSL_VERSION_NUMBER, SSLeay());
1578  }
1579  SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
1580  SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
1581  tls_server_name_call_back);
1582 #else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1583  SSL_CTX_set_client_hello_cb(context->dtls.ctx,
1584  tls_client_hello_call_back,
1585  NULL);
1586 #endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1587  }
1588  if (context->tls.ctx) {
1589  /* SERVER TLS */
1590 #if OPENSSL_VERSION_NUMBER < 0x10101000L
1591  if (!setup_pki_server(context->tls.ctx, setup_data))
1592  return 0;
1593 #endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
1594  /* libcoap is managing TLS connection based on setup_data options */
1595  /* Need to set up logic to differentiate between a PSK or PKI session */
1596  /*
1597  * For OpenSSL 1.1.1, we need to use SSL_CTX_set_client_hello_cb()
1598  * which is not in 1.1.0
1599  */
1600 #if OPENSSL_VERSION_NUMBER < 0x10101000L
1601  if (SSLeay() >= 0x10101000L) {
1603  "OpenSSL compiled with %lux, linked with %lux, so "
1604  "no certificate checking\n",
1605  OPENSSL_VERSION_NUMBER, SSLeay());
1606  }
1607  SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
1608  SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
1609  tls_server_name_call_back);
1610 #else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1611  SSL_CTX_set_client_hello_cb(context->tls.ctx,
1612  tls_client_hello_call_back,
1613  NULL);
1614 #endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1615  /* TLS Only */
1616  SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
1617  }
1618  }
1619 
1620  if (!context->dtls.ssl) {
1621  /* This is set up to handle new incoming sessions to a server */
1622  context->dtls.ssl = SSL_new(context->dtls.ctx);
1623  if (!context->dtls.ssl)
1624  return 0;
1625  bio = BIO_new(context->dtls.meth);
1626  if (!bio) {
1627  SSL_free (context->dtls.ssl);
1628  context->dtls.ssl = NULL;
1629  return 0;
1630  }
1631  SSL_set_bio(context->dtls.ssl, bio, bio);
1632  SSL_set_app_data(context->dtls.ssl, NULL);
1633  SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1634  SSL_set_mtu(context->dtls.ssl, COAP_DEFAULT_MTU);
1635  }
1636  context->psk_pki_enabled |= IS_PKI;
1637  return 1;
1638 }
1639 
1640 int
1642  const char *ca_file,
1643  const char *ca_dir
1644 ) {
1645  coap_openssl_context_t *context =
1646  ((coap_openssl_context_t *)ctx->dtls_context);
1647  if (context->dtls.ctx) {
1648  if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
1649  coap_log(LOG_WARNING, "Unable to install root CAs (%s/%s)\n",
1650  ca_file ? ca_file : "NULL", ca_dir ? ca_dir : "NULL");
1651  return 0;
1652  }
1653  }
1654  if (context->tls.ctx) {
1655  if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
1656  coap_log(LOG_WARNING, "Unable to install root CAs (%s/%s)\n",
1657  ca_file ? ca_file : "NULL", ca_dir ? ca_dir : "NULL");
1658  return 0;
1659  }
1660  }
1661  return 1;
1662 }
1663 
1664 int
1666 {
1667  coap_openssl_context_t *context =
1668  ((coap_openssl_context_t *)ctx->dtls_context);
1669  return context->psk_pki_enabled ? 1 : 0;
1670 }
1671 
1672 
1673 void coap_dtls_free_context(void *handle) {
1674  size_t i;
1675  coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
1676 
1677  if (context->dtls.ssl)
1678  SSL_free(context->dtls.ssl);
1679  if (context->dtls.ctx)
1680  SSL_CTX_free(context->dtls.ctx);
1681  if (context->dtls.cookie_hmac)
1682  HMAC_CTX_free(context->dtls.cookie_hmac);
1683  if (context->dtls.meth)
1684  BIO_meth_free(context->dtls.meth);
1685  if (context->dtls.bio_addr)
1686  BIO_ADDR_free(context->dtls.bio_addr);
1687  if ( context->tls.ctx )
1688  SSL_CTX_free( context->tls.ctx );
1689  if ( context->tls.meth )
1690  BIO_meth_free( context->tls.meth );
1691  for (i = 0; i < context->sni_count; i++) {
1692  OPENSSL_free(context->sni_entry_list[i].sni);
1693 #if OPENSSL_VERSION_NUMBER < 0x10101000L
1694  SSL_CTX_free(context->sni_entry_list[i].ctx);
1695 #endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
1696  }
1697  if (context->sni_count)
1698  OPENSSL_free(context->sni_entry_list);
1699  coap_free(context);
1700 }
1701 
1703  BIO *nbio = NULL;
1704  SSL *nssl = NULL, *ssl = NULL;
1705  coap_ssl_data *data;
1706  coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->context->dtls_context)->dtls;
1707  int r;
1708 
1709  nssl = SSL_new(dtls->ctx);
1710  if (!nssl)
1711  goto error;
1712  nbio = BIO_new(dtls->meth);
1713  if (!nbio)
1714  goto error;
1715  SSL_set_bio(nssl, nbio, nbio);
1716  SSL_set_app_data(nssl, NULL);
1717  SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
1718  SSL_set_mtu(nssl, session->mtu);
1719  ssl = dtls->ssl;
1720  dtls->ssl = nssl;
1721  nssl = NULL;
1722  SSL_set_app_data(ssl, session);
1723 
1724  data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1725  data->session = session;
1726 
1727  if (session->context->get_server_hint) {
1728  char hint[128] = "";
1729  size_t hint_len = session->context->get_server_hint(session, (uint8_t*)hint, sizeof(hint) - 1);
1730  if (hint_len > 0 && hint_len < sizeof(hint)) {
1731  hint[hint_len] = 0;
1732  SSL_use_psk_identity_hint(ssl, hint);
1733  }
1734  }
1735 
1736  r = SSL_accept(ssl);
1737  if (r == -1) {
1738  int err = SSL_get_error(ssl, r);
1739  if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
1740  r = 0;
1741  }
1742 
1743  if (r == 0) {
1744  SSL_free(ssl);
1745  return NULL;
1746  }
1747 
1748  return ssl;
1749 
1750 error:
1751  if (nssl)
1752  SSL_free(nssl);
1753  return NULL;
1754 }
1755 
1756 static int
1757 setup_client_ssl_session(coap_session_t *session, SSL *ssl
1758 ) {
1759  coap_openssl_context_t *context = ((coap_openssl_context_t *)session->context->dtls_context);
1760 
1761  if (context->psk_pki_enabled & IS_PSK) {
1762  SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
1763  SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1764  SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
1765  }
1766  if (context->psk_pki_enabled & IS_PKI) {
1767  coap_dtls_pki_t *setup_data = &context->setup_data;
1768  if (!setup_pki_ssl(ssl, setup_data, 0))
1769  return 0;
1770  /* libcoap is managing (D)TLS connection based on setup_data options */
1771  if (session->proto == COAP_PROTO_TLS)
1772  SSL_set_alpn_protos(ssl, coap_alpn, sizeof(coap_alpn));
1773 
1774  /* Issue SNI if requested */
1775  if (setup_data->client_sni &&
1776  SSL_set_tlsext_host_name (ssl, setup_data->client_sni) != 1) {
1777  coap_log(LOG_WARNING, "SSL_set_tlsext_host_name: set '%s' failed",
1778  setup_data->client_sni);
1779  }
1780  /* Certificate Revocation */
1781  if (setup_data->check_cert_revocation) {
1782  X509_VERIFY_PARAM *param;
1783 
1784  param = X509_VERIFY_PARAM_new();
1785  X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1786  SSL_set1_param(ssl, param);
1787  X509_VERIFY_PARAM_free(param);
1788  }
1789 
1790  /* Verify Peer */
1791  if (setup_data->verify_peer_cert)
1792  SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_call_back);
1793  else
1794  SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1795 
1796  /* Check CA Chain */
1797  if (setup_data->cert_chain_validation)
1798  SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth);
1799 
1800  }
1801  return 1;
1802 }
1803 
1805  BIO *bio = NULL;
1806  SSL *ssl = NULL;
1807  coap_ssl_data *data;
1808  int r;
1809  coap_openssl_context_t *context = ((coap_openssl_context_t *)session->context->dtls_context);
1810  coap_dtls_context_t *dtls = &context->dtls;
1811 
1812  ssl = SSL_new(dtls->ctx);
1813  if (!ssl)
1814  goto error;
1815  bio = BIO_new(dtls->meth);
1816  if (!bio)
1817  goto error;
1818  data = (coap_ssl_data *)BIO_get_data(bio);
1819  data->session = session;
1820  SSL_set_bio(ssl, bio, bio);
1821  SSL_set_app_data(ssl, session);
1822  SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
1823  SSL_set_mtu(ssl, session->mtu);
1824 
1825  if (!setup_client_ssl_session(session, ssl))
1826  goto error;
1827 
1828  session->dtls_timeout_count = 0;
1829 
1830  r = SSL_connect(ssl);
1831  if (r == -1) {
1832  int ret = SSL_get_error(ssl, r);
1833  if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
1834  r = 0;
1835  }
1836 
1837  if (r == 0)
1838  goto error;
1839 
1840  return ssl;
1841 
1842 error:
1843  if (ssl)
1844  SSL_free(ssl);
1845  return NULL;
1846 }
1847 
1849  SSL *ssl = (SSL *)session->tls;
1850  if (ssl)
1851  SSL_set_mtu(ssl, session->mtu);
1852 }
1853 
1854 void coap_dtls_free_session(coap_session_t *session) {
1855  SSL *ssl = (SSL *)session->tls;
1856  if (ssl) {
1857  if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
1858  int r = SSL_shutdown(ssl);
1859  if (r == 0) r = SSL_shutdown(ssl);
1860  }
1861  SSL_free(ssl);
1862  session->tls = NULL;
1863  if (session->context)
1864  coap_handle_event(session->context, COAP_EVENT_DTLS_CLOSED, session);
1865  }
1866 }
1867 
1868 int coap_dtls_send(coap_session_t *session,
1869  const uint8_t *data, size_t data_len) {
1870  int r;
1871  SSL *ssl = (SSL *)session->tls;
1872 
1873  assert(ssl != NULL);
1874 
1875  session->dtls_event = -1;
1876  r = SSL_write(ssl, data, (int)data_len);
1877 
1878  if (r <= 0) {
1879  int err = SSL_get_error(ssl, r);
1880  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1881  r = 0;
1882  } else {
1883  coap_log(LOG_WARNING, "coap_dtls_send: cannot send PDU\n");
1884  if (err == SSL_ERROR_ZERO_RETURN)
1886  else if (err == SSL_ERROR_SSL)
1887  session->dtls_event = COAP_EVENT_DTLS_ERROR;
1888  r = -1;
1889  }
1890  }
1891 
1892  if (session->dtls_event >= 0) {
1893  /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */
1894  if (session->dtls_event != COAP_EVENT_DTLS_CLOSED)
1895  coap_handle_event(session->context, session->dtls_event, session);
1896  if (session->dtls_event == COAP_EVENT_DTLS_ERROR ||
1897  session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
1899  r = -1;
1900  }
1901  }
1902 
1903  return r;
1904 }
1905 
1906 int coap_dtls_is_context_timeout(void) {
1907  return 0;
1908 }
1909 
1910 coap_tick_t coap_dtls_get_context_timeout(void *dtls_context) {
1911  (void)dtls_context;
1912  return 0;
1913 }
1914 
1916  SSL *ssl = (SSL *)session->tls;
1917  coap_ssl_data *ssl_data;
1918 
1919  assert(ssl != NULL);
1920  ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1921  return ssl_data->timeout;
1922 }
1923 
1925  SSL *ssl = (SSL *)session->tls;
1926 
1927  assert(ssl != NULL);
1928  if (((session->state == COAP_SESSION_STATE_HANDSHAKE) &&
1929  (++session->dtls_timeout_count > session->max_retransmit)) ||
1930  (DTLSv1_handle_timeout(ssl) < 0)) {
1931  /* Too many retries */
1933  }
1934 }
1935 
1936 int coap_dtls_hello(coap_session_t *session,
1937  const uint8_t *data, size_t data_len) {
1938  coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->context->dtls_context)->dtls;
1939  coap_ssl_data *ssl_data;
1940  int r;
1941 
1942  SSL_set_mtu(dtls->ssl, session->mtu);
1943  ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(dtls->ssl));
1944  ssl_data->session = session;
1945  ssl_data->pdu = data;
1946  ssl_data->pdu_len = (unsigned)data_len;
1947  r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
1948  if (r <= 0) {
1949  int err = SSL_get_error(dtls->ssl, r);
1950  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1951  /* Got a ClientHello, sent-out a VerifyRequest */
1952  r = 0;
1953  }
1954  } else {
1955  /* Got a valid answer to a VerifyRequest */
1956  r = 1;
1957  }
1958 
1959  return r;
1960 }
1961 
1962 int coap_dtls_receive(coap_session_t *session,
1963  const uint8_t *data, size_t data_len) {
1964  coap_ssl_data *ssl_data;
1965  SSL *ssl = (SSL *)session->tls;
1966  int r;
1967 
1968  assert(ssl != NULL);
1969 
1970  int in_init = SSL_in_init(ssl);
1972  ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1973  ssl_data->pdu = data;
1974  ssl_data->pdu_len = (unsigned)data_len;
1975 
1976  session->dtls_event = -1;
1977  r = SSL_read(ssl, pdu, (int)sizeof(pdu));
1978  if (r > 0) {
1979  return coap_handle_dgram(session->context, session, pdu, (size_t)r);
1980  } else {
1981  int err = SSL_get_error(ssl, r);
1982  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1983  if (in_init && SSL_is_init_finished(ssl)) {
1984  coap_log(COAP_LOG_CIPHERS, "* %s: Using cipher: %s\n",
1985  coap_session_str(session), SSL_get_cipher_name(ssl));
1987  coap_session_connected(session);
1988  }
1989  r = 0;
1990  } else {
1991  if (err == SSL_ERROR_ZERO_RETURN) /* Got a close notify alert from the remote side */
1993  else if (err == SSL_ERROR_SSL)
1994  session->dtls_event = COAP_EVENT_DTLS_ERROR;
1995  r = -1;
1996  }
1997  if (session->dtls_event >= 0) {
1998  /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */
1999  if (session->dtls_event != COAP_EVENT_DTLS_CLOSED)
2000  coap_handle_event(session->context, session->dtls_event, session);
2001  if (session->dtls_event == COAP_EVENT_DTLS_ERROR ||
2002  session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
2004  r = -1;
2005  }
2006  }
2007  }
2008 
2009  return r;
2010 }
2011 
2012 unsigned int coap_dtls_get_overhead(coap_session_t *session) {
2013  unsigned int overhead = 37;
2014  const SSL_CIPHER *s_ciph = NULL;
2015  if (session->tls != NULL)
2016  s_ciph = SSL_get_current_cipher(session->tls);
2017  if ( s_ciph ) {
2018  unsigned int ivlen, maclen, blocksize = 1, pad = 0;
2019 
2020  const EVP_CIPHER *e_ciph;
2021  const EVP_MD *e_md;
2022  char cipher[128];
2023 
2024  e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
2025 
2026  switch (EVP_CIPHER_mode(e_ciph)) {
2027  case EVP_CIPH_GCM_MODE:
2028  ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
2029  maclen = EVP_GCM_TLS_TAG_LEN;
2030  break;
2031 
2032  case EVP_CIPH_CCM_MODE:
2033  ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
2034  SSL_CIPHER_description(s_ciph, cipher, sizeof(cipher));
2035  if (strstr(cipher, "CCM8"))
2036  maclen = 8;
2037  else
2038  maclen = 16;
2039  break;
2040 
2041  case EVP_CIPH_CBC_MODE:
2042  e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
2043  blocksize = EVP_CIPHER_block_size(e_ciph);
2044  ivlen = EVP_CIPHER_iv_length(e_ciph);
2045  pad = 1;
2046  maclen = EVP_MD_size(e_md);
2047  break;
2048 
2049  case EVP_CIPH_STREAM_CIPHER:
2050  /* Seen with PSK-CHACHA20-POLY1305 */
2051  ivlen = 8;
2052  maclen = 8;
2053  break;
2054 
2055  default:
2056  SSL_CIPHER_description(s_ciph, cipher, sizeof(cipher));
2057  coap_log(LOG_WARNING, "Unknown overhead for DTLS with cipher %s\n",
2058  cipher);
2059  ivlen = 8;
2060  maclen = 16;
2061  break;
2062  }
2063  overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
2064  }
2065  return overhead;
2066 }
2067 
2068 void *coap_tls_new_client_session(coap_session_t *session, int *connected) {
2069  BIO *bio = NULL;
2070  SSL *ssl = NULL;
2071  int r;
2072  coap_openssl_context_t *context = ((coap_openssl_context_t *)session->context->dtls_context);
2073  coap_tls_context_t *tls = &context->tls;
2074 
2075  *connected = 0;
2076  ssl = SSL_new(tls->ctx);
2077  if (!ssl)
2078  goto error;
2079  bio = BIO_new(tls->meth);
2080  if (!bio)
2081  goto error;
2082  BIO_set_data(bio, session);
2083  SSL_set_bio(ssl, bio, bio);
2084  SSL_set_app_data(ssl, session);
2085 
2086  if (!setup_client_ssl_session(session, ssl))
2087  return 0;
2088 
2089  r = SSL_connect(ssl);
2090  if (r == -1) {
2091  int ret = SSL_get_error(ssl, r);
2092  if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
2093  r = 0;
2094  if (ret == SSL_ERROR_WANT_READ)
2095  session->sock.flags |= COAP_SOCKET_WANT_READ;
2096  if (ret == SSL_ERROR_WANT_WRITE) {
2097  session->sock.flags |= COAP_SOCKET_WANT_WRITE;
2098 #ifdef COAP_EPOLL_SUPPORT
2099  coap_epoll_ctl_mod(&session->sock,
2100  EPOLLOUT |
2101  ((session->sock.flags & COAP_SOCKET_WANT_READ) ?
2102  EPOLLIN : 0),
2103  __func__);
2104 #endif /* COAP_EPOLL_SUPPORT */
2105  }
2106  }
2107 
2108  if (r == 0)
2109  goto error;
2110 
2111  *connected = SSL_is_init_finished(ssl);
2112 
2113  return ssl;
2114 
2115 error:
2116  if (ssl)
2117  SSL_free(ssl);
2118  return NULL;
2119 }
2120 
2121 void *coap_tls_new_server_session(coap_session_t *session, int *connected) {
2122  BIO *bio = NULL;
2123  SSL *ssl = NULL;
2124  coap_tls_context_t *tls = &((coap_openssl_context_t *)session->context->dtls_context)->tls;
2125  int r;
2126 
2127  *connected = 0;
2128  ssl = SSL_new(tls->ctx);
2129  if (!ssl)
2130  goto error;
2131  bio = BIO_new(tls->meth);
2132  if (!bio)
2133  goto error;
2134  BIO_set_data(bio, session);
2135  SSL_set_bio(ssl, bio, bio);
2136  SSL_set_app_data(ssl, session);
2137 
2138  if (session->context->get_server_hint) {
2139  char hint[128] = "";
2140  size_t hint_len = session->context->get_server_hint(session, (uint8_t*)hint, sizeof(hint) - 1);
2141  if (hint_len > 0 && hint_len < sizeof(hint)) {
2142  hint[hint_len] = 0;
2143  SSL_use_psk_identity_hint(ssl, hint);
2144  }
2145  }
2146 
2147  r = SSL_accept(ssl);
2148  if (r == -1) {
2149  int err = SSL_get_error(ssl, r);
2150  if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2151  r = 0;
2152  if (err == SSL_ERROR_WANT_READ)
2153  session->sock.flags |= COAP_SOCKET_WANT_READ;
2154  if (err == SSL_ERROR_WANT_WRITE) {
2155  session->sock.flags |= COAP_SOCKET_WANT_WRITE;
2156 #ifdef COAP_EPOLL_SUPPORT
2157  coap_epoll_ctl_mod(&session->sock,
2158  EPOLLOUT |
2159  ((session->sock.flags & COAP_SOCKET_WANT_READ) ?
2160  EPOLLIN : 0),
2161  __func__);
2162 #endif /* COAP_EPOLL_SUPPORT */
2163  }
2164  }
2165 
2166  if (r == 0)
2167  goto error;
2168 
2169  *connected = SSL_is_init_finished(ssl);
2170 
2171  return ssl;
2172 
2173 error:
2174  if (ssl)
2175  SSL_free(ssl);
2176  return NULL;
2177 }
2178 
2179 void coap_tls_free_session(coap_session_t *session) {
2180  SSL *ssl = (SSL *)session->tls;
2181  if (ssl) {
2182  if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
2183  int r = SSL_shutdown(ssl);
2184  if (r == 0) r = SSL_shutdown(ssl);
2185  }
2186  SSL_free(ssl);
2187  session->tls = NULL;
2188  if (session->context)
2189  coap_handle_event(session->context, COAP_EVENT_DTLS_CLOSED, session);
2190  }
2191 }
2192 
2193 ssize_t coap_tls_write(coap_session_t *session,
2194  const uint8_t *data,
2195  size_t data_len
2196 ) {
2197  SSL *ssl = (SSL *)session->tls;
2198  int r, in_init;
2199 
2200  if (ssl == NULL)
2201  return -1;
2202 
2203  in_init = !SSL_is_init_finished(ssl);
2204  session->dtls_event = -1;
2205  r = SSL_write(ssl, data, (int)data_len);
2206 
2207  if (r <= 0) {
2208  int err = SSL_get_error(ssl, r);
2209  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2210  if (in_init && SSL_is_init_finished(ssl)) {
2211  coap_log(COAP_LOG_CIPHERS, "* %s: Using cipher: %s\n",
2212  coap_session_str(session), SSL_get_cipher_name(ssl));
2214  coap_session_send_csm(session);
2215  }
2216  if (err == SSL_ERROR_WANT_READ)
2217  session->sock.flags |= COAP_SOCKET_WANT_READ;
2218  if (err == SSL_ERROR_WANT_WRITE) {
2219  session->sock.flags |= COAP_SOCKET_WANT_WRITE;
2220 #ifdef COAP_EPOLL_SUPPORT
2221  coap_epoll_ctl_mod(&session->sock,
2222  EPOLLOUT |
2223  ((session->sock.flags & COAP_SOCKET_WANT_READ) ?
2224  EPOLLIN : 0),
2225  __func__);
2226 #endif /* COAP_EPOLL_SUPPORT */
2227  }
2228  r = 0;
2229  } else {
2230  coap_log(LOG_WARNING, "***%s: coap_tls_write: cannot send PDU\n",
2231  coap_session_str(session));
2232  if (err == SSL_ERROR_ZERO_RETURN)
2234  else if (err == SSL_ERROR_SSL)
2235  session->dtls_event = COAP_EVENT_DTLS_ERROR;
2236  r = -1;
2237  }
2238  } else if (in_init && SSL_is_init_finished(ssl)) {
2239  coap_log(COAP_LOG_CIPHERS, "* %s: Using cipher: %s\n",
2240  coap_session_str(session), SSL_get_cipher_name(ssl));
2242  coap_session_send_csm(session);
2243  }
2244 
2245  if (session->dtls_event >= 0) {
2246  /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */
2247  if (session->dtls_event != COAP_EVENT_DTLS_CLOSED)
2248  coap_handle_event(session->context, session->dtls_event, session);
2249  if (session->dtls_event == COAP_EVENT_DTLS_ERROR ||
2250  session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
2252  r = -1;
2253  }
2254  }
2255 
2256  return r;
2257 }
2258 
2259 ssize_t coap_tls_read(coap_session_t *session,
2260  uint8_t *data,
2261  size_t data_len
2262 ) {
2263  SSL *ssl = (SSL *)session->tls;
2264  int r, in_init;
2265 
2266  if (ssl == NULL)
2267  return -1;
2268 
2269  in_init = !SSL_is_init_finished(ssl);
2270  session->dtls_event = -1;
2271  r = SSL_read(ssl, data, (int)data_len);
2272  if (r <= 0) {
2273  int err = SSL_get_error(ssl, r);
2274  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2275  if (in_init && SSL_is_init_finished(ssl)) {
2276  coap_log(COAP_LOG_CIPHERS, "* %s: Using cipher: %s\n",
2277  coap_session_str(session), SSL_get_cipher_name(ssl));
2279  coap_session_send_csm(session);
2280  }
2281  if (err == SSL_ERROR_WANT_READ)
2282  session->sock.flags |= COAP_SOCKET_WANT_READ;
2283  if (err == SSL_ERROR_WANT_WRITE) {
2284  session->sock.flags |= COAP_SOCKET_WANT_WRITE;
2285 #ifdef COAP_EPOLL_SUPPORT
2286  coap_epoll_ctl_mod(&session->sock,
2287  EPOLLOUT |
2288  ((session->sock.flags & COAP_SOCKET_WANT_READ) ?
2289  EPOLLIN : 0),
2290  __func__);
2291 #endif /* COAP_EPOLL_SUPPORT */
2292  }
2293  r = 0;
2294  } else {
2295  if (err == SSL_ERROR_ZERO_RETURN) /* Got a close notify alert from the remote side */
2297  else if (err == SSL_ERROR_SSL)
2298  session->dtls_event = COAP_EVENT_DTLS_ERROR;
2299  r = -1;
2300  }
2301  } else if (in_init && SSL_is_init_finished(ssl)) {
2302  coap_log(COAP_LOG_CIPHERS, "* %s: Using cipher: %s\n",
2303  coap_session_str(session), SSL_get_cipher_name(ssl));
2305  coap_session_send_csm(session);
2306  }
2307 
2308  if (session->dtls_event >= 0) {
2309  /* COAP_EVENT_DTLS_CLOSED event reported in coap_session_disconnected() */
2310  if (session->dtls_event != COAP_EVENT_DTLS_CLOSED)
2311  coap_handle_event(session->context, session->dtls_event, session);
2312  if (session->dtls_event == COAP_EVENT_DTLS_ERROR ||
2313  session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
2315  r = -1;
2316  }
2317  }
2318 
2319  return r;
2320 }
2321 
2322 #else /* !HAVE_OPENSSL */
2323 
2324 #ifdef __clang__
2325 /* Make compilers happy that do not like empty modules. As this function is
2326  * never used, we ignore -Wunused-function at the end of compiling this file
2327  */
2328 #pragma GCC diagnostic ignored "-Wunused-function"
2329 #endif
2330 static inline void dummy(void) {
2331 }
2332 
2333 #endif /* HAVE_OPENSSL */
Pulls together all the internal only header files.
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
Definition: coap_io.c:735
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
Definition: coap_io.c:690
#define COAP_RXBUFFER_SIZE
Definition: coap_io.h:18
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
Definition: coap_io.h:80
@ COAP_NACK_TLS_FAILED
Definition: coap_io.h:230
#define COAP_SOCKET_WANT_WRITE
non blocking socket is waiting for writing
Definition: coap_io.h:81
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:76
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
void * coap_dtls_new_client_session(coap_session_t *session UNUSED)
Definition: coap_notls.c:96
int coap_dtls_context_set_psk(coap_context_t *ctx UNUSED, const char *hint UNUSED, coap_dtls_role_t role UNUSED)
Definition: coap_notls.c:55
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context UNUSED)
Definition: coap_notls.c:118
void * coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED)
Definition: coap_notls.c:150
int coap_dtls_receive(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
Definition: coap_notls.c:131
void * coap_dtls_new_context(struct coap_context_t *coap_context UNUSED)
Definition: coap_notls.c:84
int coap_dtls_hello(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
Definition: coap_notls.c:139
void * coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED)
Definition: coap_notls.c:154
void * coap_dtls_new_server_session(coap_session_t *session UNUSED)
Definition: coap_notls.c:92
ssize_t coap_tls_read(coap_session_t *session UNUSED, uint8_t *data UNUSED, size_t data_len UNUSED)
Definition: coap_notls.c:168
coap_tick_t coap_dtls_get_timeout(coap_session_t *session UNUSED, coap_tick_t now UNUSED)
Definition: coap_notls.c:123
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx UNUSED)
Definition: coap_notls.c:63
static int dtls_log_level
Definition: coap_notls.c:68
void coap_tls_free_session(coap_session_t *coap_session UNUSED)
Definition: coap_notls.c:158
void coap_dtls_session_update_mtu(coap_session_t *session UNUSED)
Definition: coap_notls.c:103
void coap_dtls_handle_timeout(coap_session_t *session UNUSED)
Definition: coap_notls.c:127
int coap_dtls_send(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
Definition: coap_notls.c:107
void coap_dtls_free_session(coap_session_t *coap_session UNUSED)
Definition: coap_notls.c:100
void coap_dtls_free_context(void *handle UNUSED)
Definition: coap_notls.c:89
int coap_dtls_context_set_pki(coap_context_t *ctx UNUSED, coap_dtls_pki_t *setup_data UNUSED, coap_dtls_role_t role UNUSED)
Definition: coap_notls.c:39
unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED)
Definition: coap_notls.c:146
ssize_t coap_tls_write(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
Definition: coap_notls.c:161
#define UNUSED
Definition: coap_notls.c:17
static void dummy(void)
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:288
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:216
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
Definition: coap_session.c:330
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
Definition: coap_session.c:387
#define COAP_SESSION_STATE_HANDSHAKE
Definition: coap_session.h:55
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:93
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
Definition: coap_notls.c:70
coap_dtls_role_t
Definition: coap_dtls.h:266
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
Definition: coap_notls.c:114
@ COAP_DTLS_ROLE_SERVER
Internal function invoked for server.
Definition: coap_dtls.h:268
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)
Check whether DTLS is available.
Definition: coap_notls.c:21
@ COAP_PKI_KEY_PEM
The PKI key type is PEM.
Definition: coap_dtls.h:134
@ COAP_PKI_KEY_ASN1
The PKI key type is ASN.1 (DER)
Definition: coap_dtls.h:135
@ COAP_ASN1_PKEY_DH
DH type.
Definition: coap_dtls.h:121
@ COAP_ASN1_PKEY_NONE
NONE.
Definition: coap_dtls.h:113
@ COAP_ASN1_PKEY_TLS1_PRF
TLS1_PRF type.
Definition: coap_dtls.h:126
@ COAP_ASN1_PKEY_RSA2
RSA2 type.
Definition: coap_dtls.h:115
@ COAP_ASN1_PKEY_DSA
DSA type.
Definition: coap_dtls.h:116
@ COAP_ASN1_PKEY_DHX
DHX type.
Definition: coap_dtls.h:122
@ COAP_ASN1_PKEY_DSA4
DSA4 type.
Definition: coap_dtls.h:120
@ COAP_ASN1_PKEY_DSA2
DSA2 type.
Definition: coap_dtls.h:118
@ COAP_ASN1_PKEY_RSA
RSA type.
Definition: coap_dtls.h:114
@ COAP_ASN1_PKEY_DSA1
DSA1 type.
Definition: coap_dtls.h:117
@ COAP_ASN1_PKEY_HKDF
HKDF type.
Definition: coap_dtls.h:127
@ COAP_ASN1_PKEY_EC
EC type.
Definition: coap_dtls.h:123
@ COAP_ASN1_PKEY_DSA3
DSA3 type.
Definition: coap_dtls.h:119
@ COAP_ASN1_PKEY_HMAC
HMAC type.
Definition: coap_dtls.h:124
@ COAP_ASN1_PKEY_CMAC
CMAC type.
Definition: coap_dtls.h:125
@ COAP_TLS_LIBRARY_OPENSSL
Using OpenSSL library.
Definition: coap_dtls.h:43
#define COAP_EVENT_DTLS_RENEGOTIATE
Definition: coap_event.h:35
#define COAP_EVENT_DTLS_ERROR
Definition: coap_event.h:36
#define COAP_EVENT_DTLS_CLOSED
(D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS
Definition: coap_event.h:33
#define COAP_EVENT_DTLS_CONNECTED
Definition: coap_event.h:34
void coap_dtls_set_log_level(int level)
Sets the (D)TLS logging level to the specified level.
Definition: coap_notls.c:74
const char * coap_session_str(const coap_session_t *session)
Get session description.
int coap_dtls_get_log_level(void)
Get the current (D)TLS logging.
Definition: coap_notls.c:79
#define coap_log(level,...)
Logging function.
Definition: coap_debug.h:129
@ LOG_ERR
Error.
Definition: coap_debug.h:51
@ LOG_INFO
Information.
Definition: coap_debug.h:54
@ LOG_WARNING
Warning.
Definition: coap_debug.h:52
@ LOG_DEBUG
Debug.
Definition: coap_debug.h:55
@ COAP_LOG_CIPHERS
CipherInfo.
Definition: coap_debug.h:56
#define prng(Buf, Length)
Fills Buf with Length bytes of random data.
Definition: prng.h:112
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
Definition: mem.h:75
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
Definition: mem.h:82
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:1557
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:2542
#define COAP_PROTO_TLS
Definition: pdu.h:345
#define COAP_PROTO_DTLS
Definition: pdu.h:343
#define COAP_DEFAULT_MTU
Definition: pdu.h:32
The CoAP stack's global state is stored in a coap_context_t object.
Definition: net.h:147
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:196
void * dtls_context
Definition: net.h:199
uint8_t * psk_key
Definition: net.h:202
size_t(* get_server_hint)(const coap_session_t *session, uint8_t *hint, size_t max_hint_len)
Definition: net.h:197
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:195
size_t psk_key_len
Definition: net.h:203
The structure that holds the PKI key information.
Definition: coap_dtls.h:163
coap_pki_key_pem_t pem
for PEM keys
Definition: coap_dtls.h:166
union coap_dtls_key_t::@1 key
coap_pki_key_t key_type
key format type
Definition: coap_dtls.h:164
coap_pki_key_asn1_t asn1
for ASN.1 (DER) keys
Definition: coap_dtls.h:167
The structure used for defining the PKI setup data to be used.
Definition: coap_dtls.h:193
uint8_t allow_no_crl
1 ignore if CRL not there
Definition: coap_dtls.h:204
void * cn_call_back_arg
Passed in to the CN call-back function.
Definition: coap_dtls.h:221
uint8_t require_peer_cert
1 if peer cert is required
Definition: coap_dtls.h:198
uint8_t cert_chain_validation
1 if to check cert_chain_verify_depth
Definition: coap_dtls.h:201
uint8_t check_cert_revocation
1 if revocation checks wanted
Definition: coap_dtls.h:203
uint8_t cert_chain_verify_depth
recommended depth is 3
Definition: coap_dtls.h:202
coap_dtls_security_setup_t additional_tls_setup_call_back
Additional Security call-back handler that is invoked when libcoap has done the standerd,...
Definition: coap_dtls.h:236
uint8_t allow_expired_certs
1 if expired certs are allowed
Definition: coap_dtls.h:200
uint8_t verify_peer_cert
Set to 1 to support this version of the struct.
Definition: coap_dtls.h:197
char * client_sni
If not NULL, SNI to use in client TLS setup.
Definition: coap_dtls.h:238
coap_dtls_sni_callback_t validate_sni_call_back
SNI check call-back function.
Definition: coap_dtls.h:228
uint8_t allow_self_signed
1 if self signed certs are allowed
Definition: coap_dtls.h:199
void * sni_call_back_arg
Passed in to the sni call-back function.
Definition: coap_dtls.h:229
coap_dtls_cn_callback_t validate_cn_call_back
CN check call-back function.
Definition: coap_dtls.h:220
uint8_t allow_expired_crl
1 if expired crl is allowed
Definition: coap_dtls.h:205
coap_dtls_key_t pki_key
PKI key definition.
Definition: coap_dtls.h:242
const uint8_t * private_key
ASN1 (DER) Private Key.
Definition: coap_dtls.h:153
coap_asn1_privatekey_type_t private_key_type
Private Key Type.
Definition: coap_dtls.h:157
size_t public_cert_len
ASN1 Public Cert length.
Definition: coap_dtls.h:155
size_t private_key_len
ASN1 Private Key length.
Definition: coap_dtls.h:156
const uint8_t * ca_cert
ASN1 (DER) Common CA Cert.
Definition: coap_dtls.h:151
size_t ca_cert_len
ASN1 CA Cert length.
Definition: coap_dtls.h:154
const uint8_t * public_cert
ASN1 (DER) Public Cert.
Definition: coap_dtls.h:152
const char * ca_file
File location of Common CA in PEM format.
Definition: coap_dtls.h:142
const char * public_cert
File location of Public Cert in PEM format.
Definition: coap_dtls.h:143
const char * private_key
File location of Private Key in PEM format.
Definition: coap_dtls.h:144
unsigned int dtls_timeout_count
dtls setup retry counter
Definition: coap_session.h:95
coap_socket_t sock
socket object for the session, if any
Definition: coap_session.h:70
unsigned int max_retransmit
maximum re-transmit count (default 4)
Definition: coap_session.h:92
coap_session_state_t state
current state of relationaship with peer
Definition: coap_session.h:62
coap_proto_t proto
protocol used
Definition: coap_session.h:60
struct coap_context_t * context
session's context
Definition: coap_session.h:72
int dtls_event
Tracking any (D)TLS events on this sesison.
Definition: coap_session.h:96
void * tls
security parameters
Definition: coap_session.h:73
unsigned mtu
path or CSM mtu
Definition: coap_session.h:65
coap_socket_flags_t flags
Definition: coap_io.h:62
The structure used for returning the underlying (D)TLS library information.
Definition: coap_dtls.h:51
uint64_t built_version
(D)TLS Built against Library Version
Definition: coap_dtls.h:54
coap_tls_library_t type
Library type.
Definition: coap_dtls.h:53
uint64_t version
(D)TLS runtime Library Version
Definition: coap_dtls.h:52
unsigned char uint8_t
Definition: uthash.h:79