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;
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))) {
525  if (dtls_log_level >= LOG_WARNING)
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 */
unsigned mtu
path or CSM mtu
Definition: coap_session.h:65
void coap_dtls_set_log_level(int level)
Sets the log level to the specified value.
void coap_dtls_free_session(struct coap_dtls_context_t *dtls_context, struct coap_dtls_session_t *session)
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
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
Definition: coap_io.h:76
int coap_dtls_hello(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
Definition: coap_notls.c:139
#define COAP_RXBUFFER_SIZE
Definition: coap_io.h:18
#define COAP_DEFAULT_MTU
Definition: pdu.h:32
uint8_t allow_self_signed
1 if self signed certs are allowed
Definition: coap_dtls.h:199
static void dummy(void)
void coap_tls_free_session(coap_session_t *coap_session UNUSED)
Definition: coap_notls.c:158
struct coap_context_t * context
session&#39;s context
Definition: coap_session.h:72
The PKI key type is ASN.1 (DER)
Definition: coap_dtls.h:135
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.
void * tls
security parameters
Definition: coap_session.h:73
coap_pki_key_t key_type
key format type
Definition: coap_dtls.h:164
#define COAP_SESSION_STATE_HANDSHAKE
Definition: coap_session.h:55
int coap_dtls_receive(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
Definition: coap_notls.c:131
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx UNUSED)
Definition: coap_notls.c:63
#define COAP_EVENT_DTLS_RENEGOTIATE
Definition: coap_event.h:35
size_t psk_key_len
Definition: net.h:203
ssize_t coap_tls_read(coap_session_t *session UNUSED, uint8_t *data UNUSED, size_t data_len UNUSED)
Definition: coap_notls.c:168
void coap_epoll_ctl_mod(coap_socket_t *sock, uint32_t events, const char *func)
int coap_dtls_get_log_level(void)
Returns the current log level.
#define COAP_PROTO_DTLS
Definition: pdu.h:345
void * coap_dtls_new_client_session(coap_session_t *session UNUSED)
Definition: coap_notls.c:96
Internal function invoked for server.
Definition: coap_dtls.h:268
HKDF type.
Definition: coap_dtls.h:127
int coap_dtls_is_supported(void)
Returns 1 if support for DTLS is enabled, or 0 otherwise.
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
void * coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED)
Definition: coap_notls.c:154
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
void * sni_call_back_arg
Passed in to the sni call-back function.
Definition: coap_dtls.h:229
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
Definition: coap_io.c:735
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
int dtls_event
Tracking any (D)TLS events on this sesison.
Definition: coap_session.h:96
uint8_t verify_peer_cert
Set to 1 to support this version of the struct.
Definition: coap_dtls.h:197
Debug.
Definition: coap_debug.h:55
uint8_t allow_no_crl
1 ignore if CRL not there
Definition: coap_dtls.h:204
uint64_t version
(D)TLS runtime Library Version
Definition: coap_dtls.h:52
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
RSA2 type.
Definition: coap_dtls.h:115
#define UNUSED
coap_dtls_sni_callback_t validate_sni_call_back
SNI check call-back function.
Definition: coap_dtls.h:228
HMAC type.
Definition: coap_dtls.h:124
void * coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED)
Definition: coap_notls.c:150
DSA1 type.
Definition: coap_dtls.h:117
const char * coap_session_str(const coap_session_t *session)
Get session description.
struct coap_dtls_context_t coap_dtls_context_t
DSA type.
Definition: coap_dtls.h:116
unsigned int max_retransmit
maximum re-transmit count (default 4)
Definition: coap_session.h:92
int coap_dtls_send(struct coap_context_t *coap_context, struct coap_dtls_session_t *session, const coap_pdu_t *pdu)
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
Definition: mem.h:75
coap_dtls_security_setup_t additional_tls_setup_call_back
Additional Security call-back handler that is invoked when libcoap has done the standerd, defined validation checks at the TLS level, If not NULL, called from within the TLS Client Hello connection setup.
Definition: coap_dtls.h:236
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition: coap_notls.c:26
coap_tls_library_t type
Library type.
Definition: coap_dtls.h:53
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
const char * private_key
File location of Private Key in PEM format.
Definition: coap_dtls.h:144
uint8_t require_peer_cert
1 if peer cert is required
Definition: coap_dtls.h:198
coap_proto_t proto
protocol used
Definition: coap_session.h:60
coap_dtls_key_t pki_key
PKI key definition.
Definition: coap_dtls.h:242
coap_pki_key_pem_t pem
for PEM keys
Definition: coap_dtls.h:166
char * client_sni
If not NULL, SNI to use in client TLS setup.
Definition: coap_dtls.h:238
Warning.
Definition: coap_debug.h:52
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition: coap_time.h:93
The structure that holds the PKI key information.
Definition: coap_dtls.h:163
unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED)
Definition: coap_notls.c:146
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
size_t ca_cert_len
ASN1 CA Cert length.
Definition: coap_dtls.h:154
The PKI key type is PEM.
Definition: coap_dtls.h:134
RSA type.
Definition: coap_dtls.h:114
coap_socket_t sock
socket object for the session, if any
Definition: coap_session.h:70
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
Definition: coap_io.c:690
static int dtls_log_level
Definition: coap_notls.c:68
The structure used for returning the underlying (D)TLS library information.
Definition: coap_dtls.h:51
#define COAP_EVENT_DTLS_CLOSED
(D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS
Definition: coap_event.h:33
DSA4 type.
Definition: coap_dtls.h:120
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_dtls_context_set_psk(coap_context_t *ctx UNUSED, const char *hint UNUSED, coap_dtls_role_t role UNUSED)
Definition: coap_notls.c:55
#define COAP_PROTO_TLS
Definition: pdu.h:347
uint8_t cert_chain_validation
1 if to check cert_chain_verify_depth
Definition: coap_dtls.h:201
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
Definition: mem.h:82
Error.
Definition: coap_debug.h:51
void * dtls_context
Definition: net.h:199
Using OpenSSL library.
Definition: coap_dtls.h:43
union coap_dtls_key_t::@1 key
coap_session_state_t state
current state of relationaship with peer
Definition: coap_session.h:62
const uint8_t * private_key
ASN1 (DER) Private Key.
Definition: coap_dtls.h:153
DSA3 type.
Definition: coap_dtls.h:119
coap_dtls_cn_callback_t validate_cn_call_back
CN check call-back function.
Definition: coap_dtls.h:220
uint8_t allow_expired_certs
1 if expired certs are allowed
Definition: coap_dtls.h:200
uint8_t check_cert_revocation
1 if revocation checks wanted
Definition: coap_dtls.h:203
coap_dtls_role_t
Definition: coap_dtls.h:266
size_t(* get_server_hint)(const coap_session_t *session, uint8_t *hint, size_t max_hint_len)
Definition: net.h:197
#define COAP_EVENT_DTLS_ERROR
Definition: coap_event.h:36
#define COAP_EVENT_DTLS_CONNECTED
Definition: coap_event.h:34
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
void * cn_call_back_arg
Passed in to the CN call-back function.
Definition: coap_dtls.h:221
void * coap_dtls_new_server_session(coap_session_t *session UNUSED)
Definition: coap_notls.c:92
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
Definition: coap_session.c:330
uint8_t allow_expired_crl
1 if expired crl is allowed
Definition: coap_dtls.h:205
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
Definition: coap_io.h:80
The structure used for defining the PKI setup data to be used.
Definition: coap_dtls.h:193
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
coap_asn1_privatekey_type_t private_key_type
Private Key Type.
Definition: coap_dtls.h:157
uint8_t cert_chain_verify_depth
recommended depth is 3
Definition: coap_dtls.h:202
CipherInfo.
Definition: coap_debug.h:56
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
coap_tick_t coap_ticks_from_rt_us(uint64_t t)
Helper function that converts POSIX wallclock time in us to coap ticks.
void coap_dtls_handle_timeout(coap_session_t *session UNUSED)
Definition: coap_notls.c:127
const char * public_cert
File location of Public Cert in PEM format.
Definition: coap_dtls.h:143
uint8_t * psk_key
Definition: net.h:202
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
Definition: coap_notls.c:70
coap_tick_t coap_dtls_get_timeout(coap_session_t *session UNUSED, coap_tick_t now UNUSED)
Definition: coap_notls.c:123
DSA2 type.
Definition: coap_dtls.h:118
void coap_dtls_free_context(struct coap_dtls_context_t *dtls_context)
Releases the storage allocated for dtls_context.
coap_context_t * ctx
coap_socket_flags_t flags
Definition: coap_io.h:62
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_log(level,...)
Logging function.
Definition: coap_debug.h:129
const uint8_t * ca_cert
ASN1 (DER) Common CA Cert.
Definition: coap_dtls.h:151
unsigned char uint8_t
Definition: uthash.h:79
TLS1_PRF type.
Definition: coap_dtls.h:126
size_t public_cert_len
ASN1 Public Cert length.
Definition: coap_dtls.h:155
#define prng(Buf, Length)
Fills Buf with Length bytes of random data.
Definition: prng.h:112
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context UNUSED)
Definition: coap_notls.c:118
DHX type.
Definition: coap_dtls.h:122
uint64_t built_version
(D)TLS Built against Library Version
Definition: coap_dtls.h:54
void coap_dtls_session_update_mtu(coap_session_t *session UNUSED)
Definition: coap_notls.c:103
Information.
Definition: coap_debug.h:54
unsigned int dtls_timeout_count
dtls setup retry counter
Definition: coap_session.h:95
CMAC type.
Definition: coap_dtls.h:125
The CoAP stack&#39;s global state is stored in a coap_context_t object.
Definition: net.h:147
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
Definition: coap_notls.c:114
size_t private_key_len
ASN1 Private Key length.
Definition: coap_dtls.h:156
Pulls together all the internal only header files.
coap_pki_key_asn1_t asn1
for ASN.1 (DER) keys
Definition: coap_dtls.h:167
#define COAP_SOCKET_WANT_WRITE
non blocking socket is waiting for writing
Definition: coap_io.h:81