2 * libwebsockets - small server side websockets and web server implementation
4 * Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 #include "private-libwebsockets.h"
24 #include <openssl/err.h>
27 #ifdef LWS_HAVE_OPENSSL_ECDH_H
28 #include <openssl/ecdh.h>
31 int openssl_websocket_private_data_index,
32 openssl_SSL_CTX_private_data_index;
35 lws_context_init_ssl_pem_passwd_cb(char * buf, int size, int rwflag, void *userdata)
37 struct lws_context_creation_info * info =
38 (struct lws_context_creation_info *)userdata;
40 strncpy(buf, info->ssl_private_key_password, size);
46 static void lws_ssl_bind_passphrase(SSL_CTX *ssl_ctx, struct lws_context_creation_info *info)
48 if (!info->ssl_private_key_password)
51 * password provided, set ssl callback and user data
52 * for checking password which will be trigered during
53 * SSL_CTX_use_PrivateKey_file function
55 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)info);
56 SSL_CTX_set_default_passwd_cb(ssl_ctx, lws_context_init_ssl_pem_passwd_cb);
60 lws_context_init_ssl_library(struct lws_context_creation_info *info)
64 lwsl_notice(" Compiled with CyaSSL support\n");
66 lwsl_notice(" Compiled with wolfSSL support\n");
69 lwsl_notice(" Compiled with OpenSSL support\n");
72 if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) {
73 lwsl_notice(" SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n");
77 /* basic openssl init */
81 OpenSSL_add_all_algorithms();
82 SSL_load_error_strings();
84 openssl_websocket_private_data_index =
85 SSL_get_ex_new_index(0, "lws", NULL, NULL, NULL);
87 openssl_SSL_CTX_private_data_index = SSL_CTX_get_ex_new_index(0,
88 NULL, NULL, NULL, NULL);
95 OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
102 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
103 SSL_get_ex_data_X509_STORE_CTX_idx());
106 * !!! nasty openssl requires the index to come as a library-scope
109 vh = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
112 * give him a fake wsi with context set, so he can use lws_get_context()
115 memset(&wsi, 0, sizeof(wsi));
117 wsi.context = vh->context;
119 n = vh->protocols[0].callback(&wsi,
120 LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
121 x509_ctx, ssl, preverify_ok);
123 /* convert return code from 0 = OK to 1 = OK */
128 lws_context_ssl_init_ecdh(struct lws_vhost *vhost)
130 #ifdef LWS_SSL_SERVER_WITH_ECDH_CERT
131 EC_KEY *EC_key = NULL;
136 if (!lws_check_opt(vhost->context->options, LWS_SERVER_OPTION_SSL_ECDH))
139 lwsl_notice(" Using ECDH certificate support\n");
141 /* Get X509 certificate from ssl context */
142 x = sk_X509_value(vhost->ssl_ctx->extra_certs, 0);
144 lwsl_err("%s: x is NULL\n", __func__);
147 /* Get the public key from certificate */
148 pkey = X509_get_pubkey(x);
150 lwsl_err("%s: pkey is NULL\n", __func__);
154 /* Get the key type */
155 KeyType = EVP_PKEY_type(pkey->type);
157 if (EVP_PKEY_EC != KeyType) {
158 lwsl_notice("Key type is not EC\n");
162 EC_key = EVP_PKEY_get1_EC_KEY(pkey);
163 /* Set ECDH parameter */
165 lwsl_err("%s: ECDH key is NULL \n", __func__);
168 SSL_CTX_set_tmp_ecdh(vhost->ssl_ctx, EC_key);
175 lws_context_ssl_init_ecdh_curve(struct lws_context_creation_info *info,
176 struct lws_vhost *vhost)
178 #ifdef LWS_HAVE_OPENSSL_ECDH_H
181 const char *ecdh_curve = "prime256v1";
183 if (info->ecdh_curve)
184 ecdh_curve = info->ecdh_curve;
186 ecdh_nid = OBJ_sn2nid(ecdh_curve);
187 if (NID_undef == ecdh_nid) {
188 lwsl_err("SSL: Unknown curve name '%s'", ecdh_curve);
192 ecdh = EC_KEY_new_by_curve_name(ecdh_nid);
194 lwsl_err("SSL: Unable to create curve '%s'", ecdh_curve);
197 SSL_CTX_set_tmp_ecdh(vhost->ssl_ctx, ecdh);
200 SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
202 lwsl_notice(" SSL ECDH curve '%s'\n", ecdh_curve);
204 lwsl_notice(" OpenSSL doesn't support ECDH\n");
209 #ifndef OPENSSL_NO_TLSEXT
211 lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
213 struct lws_context *context;
214 struct lws_vhost *vhost, *vh;
215 const char *servername;
219 return SSL_TLSEXT_ERR_NOACK;
221 context = (struct lws_context *)SSL_CTX_get_ex_data(
222 SSL_get_SSL_CTX(ssl),
223 openssl_SSL_CTX_private_data_index);
226 * We can only get ssl accepted connections by using a vhost's ssl_ctx
227 * find out which listening one took us and only match vhosts on the
230 vh = context->vhost_list;
232 if (vh->ssl_ctx == SSL_get_SSL_CTX(ssl))
237 assert(vh); /* we cannot get an ssl without using a vhost ssl_ctx */
238 port = vh->listen_port;
240 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
243 vhost = lws_select_vhost(context, port, servername);
245 lwsl_info("SNI: Found: %s\n", servername);
246 SSL_set_SSL_CTX(ssl, vhost->ssl_ctx);
247 return SSL_TLSEXT_ERR_OK;
249 lwsl_err("SNI: Unknown ServerName: %s\n", servername);
252 return SSL_TLSEXT_ERR_OK;
257 lws_context_init_server_ssl(struct lws_context_creation_info *info,
258 struct lws_vhost *vhost)
261 struct lws_context *context = vhost->context;
266 if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) {
271 if (info->port != CONTEXT_PORT_NO_LISTEN) {
273 vhost->use_ssl = info->ssl_cert_filepath != NULL;
275 if (vhost->use_ssl && info->ssl_cipher_list)
276 lwsl_notice(" SSL ciphers: '%s'\n", info->ssl_cipher_list);
279 lwsl_notice(" Using SSL mode\n");
281 lwsl_notice(" Using non-SSL mode\n");
285 * give him a fake wsi with context + vhost set, so he can use
286 * lws_get_context() in the callback
288 memset(&wsi, 0, sizeof(wsi));
290 wsi.context = vhost->context;
293 * Firefox insists on SSLv23 not SSLv3
294 * Konq disables SSLv2 by default now, SSLv23 works
296 * SSLv23_server_method() is the openssl method for "allow all TLS
297 * versions", compared to e.g. TLSv1_2_server_method() which only allows
298 * tlsv1.2. Unwanted versions must be disabled using SSL_CTX_set_options()
301 method = (SSL_METHOD *)SSLv23_server_method();
303 error = ERR_get_error();
304 lwsl_err("problem creating ssl method %lu: %s\n",
305 error, ERR_error_string(error,
306 (char *)context->pt[0].serv_buf));
309 vhost->ssl_ctx = SSL_CTX_new(method); /* create context */
310 if (!vhost->ssl_ctx) {
311 error = ERR_get_error();
312 lwsl_err("problem creating ssl context %lu: %s\n",
313 error, ERR_error_string(error,
314 (char *)context->pt[0].serv_buf));
318 /* associate the lws context with the SSL_CTX */
320 SSL_CTX_set_ex_data(vhost->ssl_ctx,
321 openssl_SSL_CTX_private_data_index, vhost->context);
323 /* Disable SSLv2 and SSLv3 */
324 SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
325 #ifdef SSL_OP_NO_COMPRESSION
326 SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_NO_COMPRESSION);
328 SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_SINGLE_DH_USE);
329 SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
330 if (info->ssl_cipher_list)
331 SSL_CTX_set_cipher_list(vhost->ssl_ctx,
332 info->ssl_cipher_list);
334 /* as a server, are we requiring clients to identify themselves? */
336 if (lws_check_opt(info->options, LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT)) {
337 int verify_options = SSL_VERIFY_PEER;
339 if (!lws_check_opt(info->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
340 verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
342 SSL_CTX_set_session_id_context(vhost->ssl_ctx,
343 (unsigned char *)context, sizeof(void *));
345 /* absolutely require the client cert */
347 SSL_CTX_set_verify(vhost->ssl_ctx,
348 verify_options, OpenSSL_verify_callback);
351 #ifndef OPENSSL_NO_TLSEXT
352 SSL_CTX_set_tlsext_servername_callback(vhost->ssl_ctx,
353 lws_ssl_server_name_cb);
357 * give user code a chance to load certs into the server
358 * allowing it to verify incoming client certs
361 if (info->ssl_ca_filepath &&
362 !SSL_CTX_load_verify_locations(vhost->ssl_ctx,
363 info->ssl_ca_filepath, NULL)) {
364 lwsl_err("%s: SSL_CTX_load_verify_locations unhappy\n", __func__);
367 if (vhost->use_ssl) {
368 if (lws_context_ssl_init_ecdh_curve(info, vhost))
371 vhost->protocols[0].callback(&wsi,
372 LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
373 vhost->ssl_ctx, NULL, 0);
376 if (lws_check_opt(info->options, LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT))
377 /* Normally SSL listener rejects non-ssl, optionally allow */
378 vhost->allow_non_ssl_on_ssl_port = 1;
380 if (vhost->use_ssl) {
381 /* openssl init for server sockets */
383 /* set the local certificate from CertFile */
384 n = SSL_CTX_use_certificate_chain_file(vhost->ssl_ctx,
385 info->ssl_cert_filepath);
387 error = ERR_get_error();
388 lwsl_err("problem getting cert '%s' %lu: %s\n",
389 info->ssl_cert_filepath,
391 ERR_error_string(error,
392 (char *)context->pt[0].serv_buf));
395 lws_ssl_bind_passphrase(vhost->ssl_ctx, info);
397 if (info->ssl_private_key_filepath != NULL) {
398 /* set the private key from KeyFile */
399 if (SSL_CTX_use_PrivateKey_file(vhost->ssl_ctx,
400 info->ssl_private_key_filepath,
401 SSL_FILETYPE_PEM) != 1) {
402 error = ERR_get_error();
403 lwsl_err("ssl problem getting key '%s' %lu: %s\n",
404 info->ssl_private_key_filepath, error,
405 ERR_error_string(error,
406 (char *)context->pt[0].serv_buf));
410 if (vhost->protocols[0].callback(&wsi,
411 LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
412 vhost->ssl_ctx, NULL, 0)) {
413 lwsl_err("ssl private key not set\n");
418 /* verify private key */
419 if (!SSL_CTX_check_private_key(vhost->ssl_ctx)) {
420 lwsl_err("Private SSL key doesn't match cert\n");
424 if (lws_context_ssl_init_ecdh(vhost))
428 * SSL is happy and has a cert it's content with
429 * If we're supporting HTTP2, initialize that
432 lws_context_init_http2_ssl(context);
440 lws_ssl_destroy(struct lws_vhost *vhost)
442 if (!lws_check_opt(vhost->context->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
446 SSL_CTX_free(vhost->ssl_ctx);
447 if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
448 SSL_CTX_free(vhost->ssl_client_ctx);
450 #if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
453 ERR_remove_thread_state(NULL);
457 CRYPTO_cleanup_all_ex_data();
461 lws_decode_ssl_error(void)
466 while ((err = ERR_get_error()) != 0) {
467 ERR_error_string_n(err, buf, sizeof(buf));
468 lwsl_err("*** %lu %s\n", err, buf);
472 #ifndef LWS_NO_CLIENT
475 lws_ssl_client_bio_create(struct lws *wsi)
477 struct lws_context *context = wsi->context;
478 #if defined(CYASSL_SNI_HOST_NAME) || defined(WOLFSSL_SNI_HOST_NAME) || defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
479 const char *hostname = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST);
482 wsi->ssl = SSL_new(wsi->vhost->ssl_client_ctx);
484 SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
487 * use server name indication (SNI), if supported,
488 * when establishing connection
491 #ifdef USE_OLD_CYASSL
492 #ifdef CYASSL_SNI_HOST_NAME
493 CyaSSL_UseSNI(wsi->ssl, CYASSL_SNI_HOST_NAME, hostname, strlen(hostname));
496 #ifdef WOLFSSL_SNI_HOST_NAME
497 wolfSSL_UseSNI(wsi->ssl, WOLFSSL_SNI_HOST_NAME, hostname, strlen(hostname));
501 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
502 SSL_set_tlsext_host_name(wsi->ssl, hostname);
508 * wolfSSL/CyaSSL does certificate verification differently
510 * If we should ignore the certificate, we need to set
511 * this before SSL_new and SSL_connect is called.
512 * Otherwise the connect will simply fail with error code -155
514 #ifdef USE_OLD_CYASSL
515 if (wsi->use_ssl == 2)
516 CyaSSL_set_verify(wsi->ssl, SSL_VERIFY_NONE, NULL);
518 if (wsi->use_ssl == 2)
519 wolfSSL_set_verify(wsi->ssl, SSL_VERIFY_NONE, NULL);
521 #endif /* USE_WOLFSSL */
523 wsi->client_bio = BIO_new_socket(wsi->sock, BIO_NOCLOSE);
524 SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
527 #ifdef USE_OLD_CYASSL
528 CyaSSL_set_using_nonblock(wsi->ssl, 1);
530 wolfSSL_set_using_nonblock(wsi->ssl, 1);
533 BIO_set_nbio(wsi->client_bio, 1); /* nonblocking */
536 SSL_set_ex_data(wsi->ssl, openssl_websocket_private_data_index,
543 lws_ssl_client_connect1(struct lws *wsi)
545 struct lws_context *context = wsi->context;
546 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
547 char *p = (char *)&pt->serv_buf[0];
551 lws_latency_pre(context, wsi);
552 n = SSL_connect(wsi->ssl);
553 lws_latency(context, wsi,
554 "SSL_connect LWSCM_WSCL_ISSUE_HANDSHAKE", n, n > 0);
557 n = SSL_get_error(wsi->ssl, n);
559 if (n == SSL_ERROR_WANT_READ)
562 if (n == SSL_ERROR_WANT_WRITE) {
564 * wants us to retry connect due to
565 * state of the underlying ssl layer...
566 * but since it may be stalled on
567 * blocked write, no incoming data may
568 * arrive to trigger the retry.
569 * Force (possibly many times if the SSL
570 * state persists in returning the
571 * condition code, but other sockets
572 * are getting serviced inbetweentimes)
573 * us to get called back when writable.
575 lwsl_info("%s: WANT_WRITE... retrying\n", __func__);
576 lws_callback_on_writable(wsi);
578 wsi->mode = LWSCM_WSCL_WAITING_SSL;
580 return 0; /* no error */
587 * retry if new data comes until we
588 * run into the connection timeout or win
591 if (n != SSL_ERROR_NONE) {
592 lwsl_err("SSL connect error %lu: %s\n",
593 n, ERR_error_string(n, sb));
602 lws_ssl_client_connect2(struct lws *wsi)
604 struct lws_context *context = wsi->context;
605 struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
606 char *p = (char *)&pt->serv_buf[0];
610 if (wsi->mode == LWSCM_WSCL_WAITING_SSL) {
611 lws_latency_pre(context, wsi);
612 n = SSL_connect(wsi->ssl);
613 lws_latency(context, wsi,
614 "SSL_connect LWSCM_WSCL_WAITING_SSL", n, n > 0);
617 n = SSL_get_error(wsi->ssl, n);
619 if (n == SSL_ERROR_WANT_READ) {
620 wsi->mode = LWSCM_WSCL_WAITING_SSL;
622 return 0; /* no error */
625 if (n == SSL_ERROR_WANT_WRITE) {
627 * wants us to retry connect due to
628 * state of the underlying ssl layer...
629 * but since it may be stalled on
630 * blocked write, no incoming data may
631 * arrive to trigger the retry.
632 * Force (possibly many times if the SSL
633 * state persists in returning the
634 * condition code, but other sockets
635 * are getting serviced inbetweentimes)
636 * us to get called back when writable.
638 lwsl_info("SSL_connect WANT_WRITE... retrying\n");
639 lws_callback_on_writable(wsi);
641 wsi->mode = LWSCM_WSCL_WAITING_SSL;
643 return 0; /* no error */
650 * retry if new data comes until we
651 * run into the connection timeout or win
654 if (n != SSL_ERROR_NONE) {
655 lwsl_err("SSL connect error %lu: %s\n",
656 n, ERR_error_string(n, sb));
664 * See comment above about wolfSSL certificate
667 lws_latency_pre(context, wsi);
668 n = SSL_get_verify_result(wsi->ssl);
669 lws_latency(context, wsi,
670 "SSL_get_verify_result LWS_CONNMODE..HANDSHAKE",
673 if (n != X509_V_OK) {
674 if ((n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
675 n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) && wsi->use_ssl == 2) {
676 lwsl_notice("accepting self-signed certificate\n");
678 lwsl_err("server's cert didn't look good, X509_V_ERR = %d: %s\n",
679 n, ERR_error_string(n, sb));
680 lws_close_free_wsi(wsi,
681 LWS_CLOSE_STATUS_NOSTATUS);
685 #endif /* USE_WOLFSSL */
691 int lws_context_init_client_ssl(struct lws_context_creation_info *info,
692 struct lws_vhost *vhost)
699 if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
702 if (info->provided_client_ssl_ctx) {
703 /* use the provided OpenSSL context if given one */
704 vhost->ssl_client_ctx = info->provided_client_ssl_ctx;
705 /* nothing for lib to delete */
706 vhost->user_supplied_ssl_ctx = 1;
710 if (info->port != CONTEXT_PORT_NO_LISTEN)
713 /* basic openssl init */
717 OpenSSL_add_all_algorithms();
718 SSL_load_error_strings();
720 method = (SSL_METHOD *)SSLv23_client_method();
722 error = ERR_get_error();
723 lwsl_err("problem creating ssl method %lu: %s\n",
724 error, ERR_error_string(error,
725 (char *)vhost->context->pt[0].serv_buf));
729 vhost->ssl_client_ctx = SSL_CTX_new(method);
730 if (!vhost->ssl_client_ctx) {
731 error = ERR_get_error();
732 lwsl_err("problem creating ssl context %lu: %s\n",
733 error, ERR_error_string(error,
734 (char *)vhost->context->pt[0].serv_buf));
738 #ifdef SSL_OP_NO_COMPRESSION
739 SSL_CTX_set_options(vhost->ssl_client_ctx,
740 SSL_OP_NO_COMPRESSION);
742 SSL_CTX_set_options(vhost->ssl_client_ctx,
743 SSL_OP_CIPHER_SERVER_PREFERENCE);
744 if (info->ssl_cipher_list)
745 SSL_CTX_set_cipher_list(vhost->ssl_client_ctx,
746 info->ssl_cipher_list);
748 #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
749 if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
750 /* loads OS default CA certs */
751 SSL_CTX_set_default_verify_paths(vhost->ssl_client_ctx);
754 /* openssl init for cert verification (for client sockets) */
755 if (!info->ssl_ca_filepath) {
756 if (!SSL_CTX_load_verify_locations(
757 vhost->ssl_client_ctx, NULL,
758 LWS_OPENSSL_CLIENT_CERTS))
760 "Unable to load SSL Client certs from %s "
761 "(set by --with-client-cert-dir= "
762 "in configure) -- client ssl isn't "
763 "going to work", LWS_OPENSSL_CLIENT_CERTS);
765 if (!SSL_CTX_load_verify_locations(
766 vhost->ssl_client_ctx, info->ssl_ca_filepath,
769 "Unable to load SSL Client certs "
770 "file from %s -- client ssl isn't "
771 "going to work", info->ssl_ca_filepath);
773 lwsl_info("loaded ssl_ca_filepath\n");
776 * callback allowing user code to load extra verification certs
777 * helping the client to verify server identity
780 /* support for client-side certificate authentication */
781 if (info->ssl_cert_filepath) {
782 n = SSL_CTX_use_certificate_chain_file(vhost->ssl_client_ctx,
783 info->ssl_cert_filepath);
785 lwsl_err("problem getting cert '%s' %lu: %s\n",
786 info->ssl_cert_filepath,
788 ERR_error_string(ERR_get_error(),
789 (char *)vhost->context->pt[0].serv_buf));
793 if (info->ssl_private_key_filepath) {
794 lws_ssl_bind_passphrase(vhost->ssl_client_ctx, info);
795 /* set the private key from KeyFile */
796 if (SSL_CTX_use_PrivateKey_file(vhost->ssl_client_ctx,
797 info->ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
798 lwsl_err("use_PrivateKey_file '%s' %lu: %s\n",
799 info->ssl_private_key_filepath,
801 ERR_error_string(ERR_get_error(),
802 (char *)vhost->context->pt[0].serv_buf));
806 /* verify private key */
807 if (!SSL_CTX_check_private_key(vhost->ssl_client_ctx)) {
808 lwsl_err("Private SSL key doesn't match cert\n");
814 * give him a fake wsi with context set, so he can use
815 * lws_get_context() in the callback
817 memset(&wsi, 0, sizeof(wsi));
819 wsi.context = vhost->context;
821 vhost->protocols[0].callback(&wsi,
822 LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
823 vhost->ssl_client_ctx, NULL, 0);
830 lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi)
832 struct lws_context *context = wsi->context;
833 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
835 if (!wsi->pending_read_list_prev &&
836 !wsi->pending_read_list_next &&
837 pt->pending_read_list != wsi)
838 /* we are not on the list */
841 /* point previous guy's next to our next */
842 if (!wsi->pending_read_list_prev)
843 pt->pending_read_list = wsi->pending_read_list_next;
845 wsi->pending_read_list_prev->pending_read_list_next =
846 wsi->pending_read_list_next;
848 /* point next guy's previous to our previous */
849 if (wsi->pending_read_list_next)
850 wsi->pending_read_list_next->pending_read_list_prev =
851 wsi->pending_read_list_prev;
853 wsi->pending_read_list_prev = NULL;
854 wsi->pending_read_list_next = NULL;
858 lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
860 struct lws_context *context = wsi->context;
861 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
865 return lws_ssl_capable_read_no_ssl(wsi, buf, len);
867 n = SSL_read(wsi->ssl, buf, len);
868 /* manpage: returning 0 means connection shut down */
870 return LWS_SSL_CAPABLE_ERROR;
873 n = SSL_get_error(wsi->ssl, n);
874 if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE)
875 return LWS_SSL_CAPABLE_MORE_SERVICE;
877 return LWS_SSL_CAPABLE_ERROR;
881 * if it was our buffer that limited what we read,
882 * check if SSL has additional data pending inside SSL buffers.
884 * Because these won't signal at the network layer with POLLIN
885 * and if we don't realize, this data will sit there forever
891 if (!SSL_pending(wsi->ssl))
893 if (wsi->pending_read_list_next)
895 if (wsi->pending_read_list_prev)
897 if (pt->pending_read_list == wsi)
900 /* add us to the linked list of guys with pending ssl */
901 if (pt->pending_read_list)
902 pt->pending_read_list->pending_read_list_prev = wsi;
904 wsi->pending_read_list_next = pt->pending_read_list;
905 wsi->pending_read_list_prev = NULL;
906 pt->pending_read_list = wsi;
910 lws_ssl_remove_wsi_from_buffered_list(wsi);
916 lws_ssl_pending(struct lws *wsi)
921 return SSL_pending(wsi->ssl);
925 lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
930 return lws_ssl_capable_write_no_ssl(wsi, buf, len);
932 n = SSL_write(wsi->ssl, buf, len);
936 n = SSL_get_error(wsi->ssl, n);
937 if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE) {
938 if (n == SSL_ERROR_WANT_WRITE)
939 lws_set_blocking_send(wsi);
940 return LWS_SSL_CAPABLE_MORE_SERVICE;
943 return LWS_SSL_CAPABLE_ERROR;
947 lws_ssl_close(struct lws *wsi)
952 return 0; /* not handled */
954 n = SSL_get_fd(wsi->ssl);
955 SSL_shutdown(wsi->ssl);
960 return 1; /* handled */
963 /* leave all wsi close processing to the caller */
966 lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
968 struct lws_context *context = wsi->context;
969 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
975 if (!LWS_SSL_ENABLED(wsi->vhost))
981 wsi->ssl = SSL_new(wsi->vhost->ssl_ctx);
982 if (wsi->ssl == NULL) {
983 lwsl_err("SSL_new failed: %s\n",
984 ERR_error_string(SSL_get_error(wsi->ssl, 0), NULL));
985 lws_decode_ssl_error();
986 if (accept_fd != LWS_SOCK_INVALID)
987 compatible_close(accept_fd);
991 SSL_set_ex_data(wsi->ssl,
992 openssl_websocket_private_data_index, context);
994 SSL_set_fd(wsi->ssl, accept_fd);
997 #ifdef USE_OLD_CYASSL
998 CyaSSL_set_using_nonblock(wsi->ssl, 1);
1000 wolfSSL_set_using_nonblock(wsi->ssl, 1);
1003 SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1004 bio = SSL_get_rbio(wsi->ssl);
1006 BIO_set_nbio(bio, 1); /* nonblocking */
1008 lwsl_notice("NULL rbio\n");
1009 bio = SSL_get_wbio(wsi->ssl);
1011 BIO_set_nbio(bio, 1); /* nonblocking */
1013 lwsl_notice("NULL rbio\n");
1017 * we are not accepted yet, but we need to enter ourselves
1018 * as a live connection. That way we can retry when more
1019 * pieces come if we're not sorted yet
1022 wsi->mode = LWSCM_SSL_ACK_PENDING;
1023 if (insert_wsi_socket_into_fds(context, wsi))
1026 lws_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT,
1027 context->timeout_secs);
1029 lwsl_info("inserted SSL accept into fds, trying SSL_accept\n");
1033 case LWSCM_SSL_ACK_PENDING:
1035 if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
1038 lws_latency_pre(context, wsi);
1040 n = recv(wsi->sock, (char *)pt->serv_buf, LWS_MAX_SOCKET_IO_BUF,
1044 * optionally allow non-SSL connect on SSL listening socket
1045 * This is disabled by default, if enabled it goes around any
1046 * SSL-level access control (eg, client-side certs) so leave
1047 * it disabled unless you know it's not a problem for you
1050 if (wsi->vhost->allow_non_ssl_on_ssl_port) {
1051 if (n >= 1 && pt->serv_buf[0] >= ' ') {
1053 * TLS content-type for Handshake is 0x16, and
1054 * for ChangeCipherSpec Record, it's 0x14
1056 * A non-ssl session will start with the HTTP
1057 * method in ASCII. If we see it's not a legit
1058 * SSL handshake kill the SSL for this
1059 * connection and try to handle as a HTTP
1060 * connection upgrade directly.
1063 SSL_shutdown(wsi->ssl);
1066 if (lws_check_opt(context->options,
1067 LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS))
1068 wsi->redirect_to_https = 1;
1072 * connection is gone, or nothing to read
1073 * if it's gone, we will timeout on
1074 * PENDING_TIMEOUT_SSL_ACCEPT
1077 if (n < 0 && (LWS_ERRNO == LWS_EAGAIN ||
1078 LWS_ERRNO == LWS_EWOULDBLOCK)) {
1080 * well, we get no way to know ssl or not
1081 * so go around again waiting for something
1082 * to come and give us a hint, or timeout the
1085 m = SSL_ERROR_WANT_READ;
1090 /* normal SSL connection processing path */
1092 n = SSL_accept(wsi->ssl);
1093 lws_latency(context, wsi,
1094 "SSL_accept LWSCM_SSL_ACK_PENDING\n", n, n == 1);
1099 m = SSL_get_error(wsi->ssl, n);
1100 lwsl_debug("SSL_accept failed %d / %s\n",
1101 m, ERR_error_string(m, NULL));
1103 if (m == SSL_ERROR_WANT_READ) {
1104 if (lws_change_pollfd(wsi, 0, LWS_POLLIN))
1107 lwsl_info("SSL_ERROR_WANT_READ\n");
1110 if (m == SSL_ERROR_WANT_WRITE) {
1111 if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
1116 lwsl_debug("SSL_accept failed skt %u: %s\n",
1117 wsi->sock, ERR_error_string(m, NULL));
1121 /* OK, we are accepted... give him some time to negotiate */
1122 lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
1123 context->timeout_secs);
1125 wsi->mode = LWSCM_HTTP_SERVING;
1127 lws_http2_configure_if_upgraded(wsi);
1129 lwsl_debug("accepted new SSL conn\n");
1140 lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
1143 SSL_CTX_free(vhost->ssl_ctx);
1144 if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
1145 SSL_CTX_free(vhost->ssl_client_ctx);
1149 lws_ssl_context_destroy(struct lws_context *context)
1151 #if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
1152 ERR_remove_state(0);
1154 ERR_remove_thread_state(NULL);
1158 CRYPTO_cleanup_all_ex_data();