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