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