• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
coap_dtls_is_supported(void)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 
coap_tls_is_supported(void)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 
153 coap_tls_version_t *
coap_get_tls_library_version(void)154 coap_get_tls_library_version(void) {
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 
coap_dtls_startup(void)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 
coap_dtls_set_log_level(int level)169 void coap_dtls_set_log_level(int level) {
170   dtls_log_level = level;
171 }
172 
coap_dtls_get_log_level(void)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 
coap_dgram_create(BIO * a)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 
coap_dgram_destroy(BIO * a)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 
coap_dgram_read(BIO * a,char * out,int outl)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 
coap_dgram_write(BIO * a,const char * in,int inl)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 
coap_dgram_puts(BIO * a,const char * pstr)254 static int coap_dgram_puts(BIO *a, const char *pstr) {
255   return coap_dgram_write(a, pstr, (int)strlen(pstr));
256 }
257 
coap_dgram_ctrl(BIO * a,int cmd,long num,void * ptr)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 
coap_dtls_generate_cookie(SSL * ssl,unsigned char * cookie,unsigned int * cookie_len)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 
coap_dtls_verify_cookie(SSL * ssl,const uint8_t * cookie,unsigned int cookie_len)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 
coap_dtls_psk_client_callback(SSL * ssl,const char * hint,char * identity,unsigned int max_identity_len,unsigned char * buf,unsigned max_len)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 
coap_dtls_psk_server_callback(SSL * ssl,const char * identity,unsigned char * buf,unsigned max_len)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 
coap_dtls_info_callback(const SSL * ssl,int where,int ret)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)
404       session->dtls_event = COAP_EVENT_DTLS_ERROR;
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)
433     session->dtls_event = COAP_EVENT_DTLS_RENEGOTIATE;
434 }
435 
coap_sock_create(BIO * a)436 static int coap_sock_create(BIO *a) {
437   BIO_set_init(a, 1);
438   return 1;
439 }
440 
coap_sock_destroy(BIO * a)441 static int coap_sock_destroy(BIO *a) {
442   (void)a;
443   return 1;
444 }
445 
coap_sock_read(BIO * a,char * out,int outl)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 
coap_sock_write(BIO * a,const char * in,int inl)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 
coap_sock_puts(BIO * a,const char * pstr)477 static int coap_sock_puts(BIO *a, const char *pstr) {
478   return coap_sock_write(a, pstr, (int)strlen(pstr));
479 }
480 
coap_sock_ctrl(BIO * a,int cmd,long num,void * ptr)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 
coap_dtls_new_context(struct coap_context_t * coap_context)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)
526         coap_log(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
coap_dtls_context_set_psk(coap_context_t * ctx,const char * identity_hint,coap_dtls_role_t role)577 coap_dtls_context_set_psk(coap_context_t *ctx,
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
map_key_type(int asn1_private_key_type)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:
630     coap_log(LOG_WARNING,
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
server_alpn_callback(SSL * ssl UNUSED,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg UNUSED)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
add_ca_to_cert_store(X509_STORE * st,X509 * x509)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
setup_pki_server(SSL_CTX * ctx,coap_dtls_pki_t * setup_data)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))) {
696         coap_log(LOG_WARNING,
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 {
704       coap_log(LOG_ERR,
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))) {
714         coap_log(LOG_WARNING,
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 {
722       coap_log(LOG_ERR,
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 {
738         coap_log(LOG_WARNING,
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))) {
770         coap_log(LOG_WARNING,
771                  "*** setup_pki: (D)TLS: %s: Unable to configure "
772                  "Server Certificate\n",
773                  "ASN1");
774         return 0;
775       }
776     }
777     else {
778       coap_log(LOG_ERR,
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))) {
789         coap_log(LOG_WARNING,
790                  "*** setup_pki: (D)TLS: %s: Unable to configure "
791                  "Server Private Key\n",
792                  "ASN1");
793         return 0;
794       }
795     }
796     else {
797       coap_log(LOG_ERR,
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)) {
809         coap_log(LOG_WARNING,
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:
822     coap_log(LOG_ERR,
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
setup_pki_ssl(SSL * ssl,coap_dtls_pki_t * setup_data,coap_dtls_role_t role)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))) {
843         coap_log(LOG_WARNING,
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])) {
854       coap_log(LOG_ERR,
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))) {
864         coap_log(LOG_WARNING,
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])) {
874       coap_log(LOG_ERR,
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 {
893           coap_log(LOG_WARNING,
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))) {
928         coap_log(LOG_WARNING,
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])) {
939       coap_log(LOG_ERR,
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))) {
950         coap_log(LOG_WARNING,
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)) {
961       coap_log(LOG_ERR,
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)) {
976           coap_log(LOG_WARNING,
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:
992     coap_log(LOG_ERR,
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*
get_san_or_cn_from_cert(X509 * x509)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
tls_verify_call_back(int preverify_ok,X509_STORE_CTX * ctx)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) {
1095         coap_log(LOG_WARNING,
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 {
1103         coap_log(LOG_WARNING,
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
tls_secret_call_back(SSL * ssl,void * secret UNUSED,int * secretlen UNUSED,STACK_OF (SSL_CIPHER)* peer_ciphers,const SSL_CIPHER ** cipher UNUSED,void * arg)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
tls_server_name_call_back(SSL * ssl,int * sd UNUSED,void * arg)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
tls_client_hello_call_back(SSL * ssl,int * al,void * arg UNUSED)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
coap_dtls_context_set_pki(coap_context_t * ctx,coap_dtls_pki_t * setup_data,coap_dtls_role_t role)1549 coap_dtls_context_set_pki(coap_context_t *ctx,
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) {
1574         coap_log(LOG_WARNING,
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) {
1602         coap_log(LOG_WARNING,
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
coap_dtls_context_set_pki_root_cas(struct coap_context_t * ctx,const char * ca_file,const char * ca_dir)1641 coap_dtls_context_set_pki_root_cas(struct coap_context_t *ctx,
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
coap_dtls_context_check_keys_enabled(coap_context_t * ctx)1665 coap_dtls_context_check_keys_enabled(coap_context_t *ctx)
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 
coap_dtls_free_context(void * handle)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 
coap_dtls_new_server_session(coap_session_t * session)1702 void * coap_dtls_new_server_session(coap_session_t *session) {
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
setup_client_ssl_session(coap_session_t * session,SSL * ssl)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 
coap_dtls_new_client_session(coap_session_t * session)1804 void *coap_dtls_new_client_session(coap_session_t *session) {
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 
coap_dtls_session_update_mtu(coap_session_t * session)1848 void coap_dtls_session_update_mtu(coap_session_t *session) {
1849   SSL *ssl = (SSL *)session->tls;
1850   if (ssl)
1851     SSL_set_mtu(ssl, session->mtu);
1852 }
1853 
coap_dtls_free_session(coap_session_t * session)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 
coap_dtls_send(coap_session_t * session,const uint8_t * data,size_t data_len)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)
1885         session->dtls_event = COAP_EVENT_DTLS_CLOSED;
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) {
1898       coap_session_disconnected(session, COAP_NACK_TLS_FAILED);
1899       r = -1;
1900     }
1901   }
1902 
1903   return r;
1904 }
1905 
coap_dtls_is_context_timeout(void)1906 int coap_dtls_is_context_timeout(void) {
1907   return 0;
1908 }
1909 
coap_dtls_get_context_timeout(void * dtls_context)1910 coap_tick_t coap_dtls_get_context_timeout(void *dtls_context) {
1911   (void)dtls_context;
1912   return 0;
1913 }
1914 
coap_dtls_get_timeout(coap_session_t * session,coap_tick_t now UNUSED)1915 coap_tick_t coap_dtls_get_timeout(coap_session_t *session, coap_tick_t now UNUSED) {
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 
coap_dtls_handle_timeout(coap_session_t * session)1924 void coap_dtls_handle_timeout(coap_session_t *session) {
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 */
1932     coap_session_disconnected(session, COAP_NACK_TLS_FAILED);
1933   }
1934 }
1935 
coap_dtls_hello(coap_session_t * session,const uint8_t * data,size_t data_len)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 
coap_dtls_receive(coap_session_t * session,const uint8_t * data,size_t data_len)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);
1971   uint8_t pdu[COAP_RXBUFFER_SIZE];
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));
1986         coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session);
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 */
1992         session->dtls_event = COAP_EVENT_DTLS_CLOSED;
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) {
2003         coap_session_disconnected(session, COAP_NACK_TLS_FAILED);
2004         r = -1;
2005       }
2006     }
2007   }
2008 
2009   return r;
2010 }
2011 
coap_dtls_get_overhead(coap_session_t * session)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 
coap_tls_new_client_session(coap_session_t * session,int * connected)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 
coap_tls_new_server_session(coap_session_t * session,int * connected)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 
coap_tls_free_session(coap_session_t * session)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 
coap_tls_write(coap_session_t * session,const uint8_t * data,size_t data_len)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));
2213         coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session);
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)
2233         session->dtls_event = COAP_EVENT_DTLS_CLOSED;
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));
2241     coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session);
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) {
2251       coap_session_disconnected(session, COAP_NACK_TLS_FAILED);
2252       r = -1;
2253     }
2254   }
2255 
2256   return r;
2257 }
2258 
coap_tls_read(coap_session_t * session,uint8_t * data,size_t data_len)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));
2278         coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session);
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 */
2296         session->dtls_event = COAP_EVENT_DTLS_CLOSED;
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));
2304     coap_handle_event(session->context, COAP_EVENT_DTLS_CONNECTED, session);
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) {
2314       coap_session_disconnected(session, COAP_NACK_TLS_FAILED);
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
dummy(void)2330 static inline void dummy(void) {
2331 }
2332 
2333 #endif /* HAVE_OPENSSL */
2334