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