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
474 int lws_context_init_client_ssl(struct lws_context_creation_info *info,
475 struct lws_vhost *vhost)
482 if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
485 if (info->provided_client_ssl_ctx) {
486 /* use the provided OpenSSL context if given one */
487 vhost->ssl_client_ctx = info->provided_client_ssl_ctx;
488 /* nothing for lib to delete */
489 vhost->user_supplied_ssl_ctx = 1;
493 if (info->port != CONTEXT_PORT_NO_LISTEN)
496 /* basic openssl init */
500 OpenSSL_add_all_algorithms();
501 SSL_load_error_strings();
503 method = (SSL_METHOD *)SSLv23_client_method();
505 error = ERR_get_error();
506 lwsl_err("problem creating ssl method %lu: %s\n",
507 error, ERR_error_string(error,
508 (char *)vhost->context->pt[0].serv_buf));
512 vhost->ssl_client_ctx = SSL_CTX_new(method);
513 if (!vhost->ssl_client_ctx) {
514 error = ERR_get_error();
515 lwsl_err("problem creating ssl context %lu: %s\n",
516 error, ERR_error_string(error,
517 (char *)vhost->context->pt[0].serv_buf));
521 #ifdef SSL_OP_NO_COMPRESSION
522 SSL_CTX_set_options(vhost->ssl_client_ctx,
523 SSL_OP_NO_COMPRESSION);
525 SSL_CTX_set_options(vhost->ssl_client_ctx,
526 SSL_OP_CIPHER_SERVER_PREFERENCE);
527 if (info->ssl_cipher_list)
528 SSL_CTX_set_cipher_list(vhost->ssl_client_ctx,
529 info->ssl_cipher_list);
531 #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
532 if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
533 /* loads OS default CA certs */
534 SSL_CTX_set_default_verify_paths(vhost->ssl_client_ctx);
537 /* openssl init for cert verification (for client sockets) */
538 if (!info->ssl_ca_filepath) {
539 if (!SSL_CTX_load_verify_locations(
540 vhost->ssl_client_ctx, NULL,
541 LWS_OPENSSL_CLIENT_CERTS))
543 "Unable to load SSL Client certs from %s "
544 "(set by --with-client-cert-dir= "
545 "in configure) -- client ssl isn't "
546 "going to work", LWS_OPENSSL_CLIENT_CERTS);
548 if (!SSL_CTX_load_verify_locations(
549 vhost->ssl_client_ctx, info->ssl_ca_filepath,
552 "Unable to load SSL Client certs "
553 "file from %s -- client ssl isn't "
554 "going to work", info->ssl_ca_filepath);
556 lwsl_info("loaded ssl_ca_filepath\n");
559 * callback allowing user code to load extra verification certs
560 * helping the client to verify server identity
563 /* support for client-side certificate authentication */
564 if (info->ssl_cert_filepath) {
565 n = SSL_CTX_use_certificate_chain_file(vhost->ssl_client_ctx,
566 info->ssl_cert_filepath);
568 lwsl_err("problem getting cert '%s' %lu: %s\n",
569 info->ssl_cert_filepath,
571 ERR_error_string(ERR_get_error(),
572 (char *)vhost->context->pt[0].serv_buf));
576 if (info->ssl_private_key_filepath) {
577 lws_ssl_bind_passphrase(vhost->ssl_client_ctx, info);
578 /* set the private key from KeyFile */
579 if (SSL_CTX_use_PrivateKey_file(vhost->ssl_client_ctx,
580 info->ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
581 lwsl_err("use_PrivateKey_file '%s' %lu: %s\n",
582 info->ssl_private_key_filepath,
584 ERR_error_string(ERR_get_error(),
585 (char *)vhost->context->pt[0].serv_buf));
589 /* verify private key */
590 if (!SSL_CTX_check_private_key(vhost->ssl_client_ctx)) {
591 lwsl_err("Private SSL key doesn't match cert\n");
597 * give him a fake wsi with context set, so he can use
598 * lws_get_context() in the callback
600 memset(&wsi, 0, sizeof(wsi));
602 wsi.context = vhost->context;
604 vhost->protocols[0].callback(&wsi,
605 LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
606 vhost->ssl_client_ctx, NULL, 0);
613 lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi)
615 struct lws_context *context = wsi->context;
616 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
618 if (!wsi->pending_read_list_prev &&
619 !wsi->pending_read_list_next &&
620 pt->pending_read_list != wsi)
621 /* we are not on the list */
624 /* point previous guy's next to our next */
625 if (!wsi->pending_read_list_prev)
626 pt->pending_read_list = wsi->pending_read_list_next;
628 wsi->pending_read_list_prev->pending_read_list_next =
629 wsi->pending_read_list_next;
631 /* point next guy's previous to our previous */
632 if (wsi->pending_read_list_next)
633 wsi->pending_read_list_next->pending_read_list_prev =
634 wsi->pending_read_list_prev;
636 wsi->pending_read_list_prev = NULL;
637 wsi->pending_read_list_next = NULL;
641 lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
643 struct lws_context *context = wsi->context;
644 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
648 return lws_ssl_capable_read_no_ssl(wsi, buf, len);
650 n = SSL_read(wsi->ssl, buf, len);
651 /* manpage: returning 0 means connection shut down */
653 return LWS_SSL_CAPABLE_ERROR;
656 n = SSL_get_error(wsi->ssl, n);
657 if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE)
658 return LWS_SSL_CAPABLE_MORE_SERVICE;
660 return LWS_SSL_CAPABLE_ERROR;
664 * if it was our buffer that limited what we read,
665 * check if SSL has additional data pending inside SSL buffers.
667 * Because these won't signal at the network layer with POLLIN
668 * and if we don't realize, this data will sit there forever
674 if (!SSL_pending(wsi->ssl))
676 if (wsi->pending_read_list_next)
678 if (wsi->pending_read_list_prev)
680 if (pt->pending_read_list == wsi)
683 /* add us to the linked list of guys with pending ssl */
684 if (pt->pending_read_list)
685 pt->pending_read_list->pending_read_list_prev = wsi;
687 wsi->pending_read_list_next = pt->pending_read_list;
688 wsi->pending_read_list_prev = NULL;
689 pt->pending_read_list = wsi;
693 lws_ssl_remove_wsi_from_buffered_list(wsi);
699 lws_ssl_pending(struct lws *wsi)
704 return SSL_pending(wsi->ssl);
708 lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
713 return lws_ssl_capable_write_no_ssl(wsi, buf, len);
715 n = SSL_write(wsi->ssl, buf, len);
719 n = SSL_get_error(wsi->ssl, n);
720 if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE) {
721 if (n == SSL_ERROR_WANT_WRITE)
722 lws_set_blocking_send(wsi);
723 return LWS_SSL_CAPABLE_MORE_SERVICE;
726 return LWS_SSL_CAPABLE_ERROR;
730 lws_ssl_close(struct lws *wsi)
735 return 0; /* not handled */
737 n = SSL_get_fd(wsi->ssl);
738 SSL_shutdown(wsi->ssl);
743 return 1; /* handled */
746 /* leave all wsi close processing to the caller */
749 lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
751 struct lws_context *context = wsi->context;
752 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
758 if (!LWS_SSL_ENABLED(wsi->vhost))
764 wsi->ssl = SSL_new(wsi->vhost->ssl_ctx);
765 if (wsi->ssl == NULL) {
766 lwsl_err("SSL_new failed: %s\n",
767 ERR_error_string(SSL_get_error(wsi->ssl, 0), NULL));
768 lws_decode_ssl_error();
769 if (accept_fd != LWS_SOCK_INVALID)
770 compatible_close(accept_fd);
774 SSL_set_ex_data(wsi->ssl,
775 openssl_websocket_private_data_index, context);
777 SSL_set_fd(wsi->ssl, accept_fd);
780 #ifdef USE_OLD_CYASSL
781 CyaSSL_set_using_nonblock(wsi->ssl, 1);
783 wolfSSL_set_using_nonblock(wsi->ssl, 1);
786 SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
787 bio = SSL_get_rbio(wsi->ssl);
789 BIO_set_nbio(bio, 1); /* nonblocking */
791 lwsl_notice("NULL rbio\n");
792 bio = SSL_get_wbio(wsi->ssl);
794 BIO_set_nbio(bio, 1); /* nonblocking */
796 lwsl_notice("NULL rbio\n");
800 * we are not accepted yet, but we need to enter ourselves
801 * as a live connection. That way we can retry when more
802 * pieces come if we're not sorted yet
805 wsi->mode = LWSCM_SSL_ACK_PENDING;
806 if (insert_wsi_socket_into_fds(context, wsi))
809 lws_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT,
810 context->timeout_secs);
812 lwsl_info("inserted SSL accept into fds, trying SSL_accept\n");
816 case LWSCM_SSL_ACK_PENDING:
818 if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
821 lws_latency_pre(context, wsi);
823 n = recv(wsi->sock, (char *)pt->serv_buf, LWS_MAX_SOCKET_IO_BUF,
827 * optionally allow non-SSL connect on SSL listening socket
828 * This is disabled by default, if enabled it goes around any
829 * SSL-level access control (eg, client-side certs) so leave
830 * it disabled unless you know it's not a problem for you
833 if (wsi->vhost->allow_non_ssl_on_ssl_port) {
834 if (n >= 1 && pt->serv_buf[0] >= ' ') {
836 * TLS content-type for Handshake is 0x16, and
837 * for ChangeCipherSpec Record, it's 0x14
839 * A non-ssl session will start with the HTTP
840 * method in ASCII. If we see it's not a legit
841 * SSL handshake kill the SSL for this
842 * connection and try to handle as a HTTP
843 * connection upgrade directly.
846 SSL_shutdown(wsi->ssl);
849 if (lws_check_opt(context->options,
850 LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS))
851 wsi->redirect_to_https = 1;
855 * connection is gone, or nothing to read
856 * if it's gone, we will timeout on
857 * PENDING_TIMEOUT_SSL_ACCEPT
860 if (n < 0 && (LWS_ERRNO == LWS_EAGAIN ||
861 LWS_ERRNO == LWS_EWOULDBLOCK)) {
863 * well, we get no way to know ssl or not
864 * so go around again waiting for something
865 * to come and give us a hint, or timeout the
868 m = SSL_ERROR_WANT_READ;
873 /* normal SSL connection processing path */
875 n = SSL_accept(wsi->ssl);
876 lws_latency(context, wsi,
877 "SSL_accept LWSCM_SSL_ACK_PENDING\n", n, n == 1);
882 m = SSL_get_error(wsi->ssl, n);
883 lwsl_debug("SSL_accept failed %d / %s\n",
884 m, ERR_error_string(m, NULL));
886 if (m == SSL_ERROR_WANT_READ) {
887 if (lws_change_pollfd(wsi, 0, LWS_POLLIN))
890 lwsl_info("SSL_ERROR_WANT_READ\n");
893 if (m == SSL_ERROR_WANT_WRITE) {
894 if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
899 lwsl_debug("SSL_accept failed skt %u: %s\n",
900 wsi->sock, ERR_error_string(m, NULL));
904 /* OK, we are accepted... give him some time to negotiate */
905 lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
906 context->timeout_secs);
908 wsi->mode = LWSCM_HTTP_SERVING;
910 lws_http2_configure_if_upgraded(wsi);
912 lwsl_debug("accepted new SSL conn\n");
923 lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
926 SSL_CTX_free(vhost->ssl_ctx);
927 if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
928 SSL_CTX_free(vhost->ssl_client_ctx);
932 lws_ssl_context_destroy(struct lws_context *context)
934 #if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
937 ERR_remove_thread_state(NULL);
941 CRYPTO_cleanup_all_ex_data();