1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

refactor: also migrate tls to the ops struct and private.h pattern

Several new ops are planned for tls... so better to bite the bullet and
clean it out to the same level as roles + event-libs first.

Also adds a new travis target "mbedtls" and all the tests except
autobahn against mbedtls build.
This commit is contained in:
Andy Green 2018-05-01 12:41:42 +08:00
parent da0be64f68
commit bce8cca042
35 changed files with 614 additions and 483 deletions

View file

@ -6,6 +6,7 @@ env:
matrix:
- LWS_METHOD=lwsws CMAKE_ARGS="-DLWS_WITH_LWSWS=ON -DLWS_WITHOUT_EXTENSIONS=0 -DLWS_WITH_HTTP2=1 -DLWS_WITH_ACME=1 -DLWS_WITH_MINIMAL_EXAMPLES=1 -DCMAKE_BUILD_TYPE=DEBUG"
- LWS_METHOD=default CMAKE_ARGS="-DLWS_WITH_MINIMAL_EXAMPLES=1"
- LWS_METHOD=mbedtls CMAKE_ARGS="-DLWS_WITH_MBEDTLS=1 -DLWS_WITH_HTTP2=1 -DLWS_WITH_LWSWS=1 -DLWS_WITH_MINIMAL_EXAMPLES=1 -DCMAKE_BUILD_TYPE=DEBUG"
- LWS_METHOD=noserver CMAKE_ARGS="-DLWS_WITHOUT_SERVER=ON -DLWS_WITH_MINIMAL_EXAMPLES=1"
- LWS_METHOD=noclient CMAKE_ARGS="-DLWS_WITHOUT_CLIENT=ON -DLWS_WITH_MINIMAL_EXAMPLES=1"
- LWS_METHOD=noext CMAKE_ARGS="-DLWS_WITHOUT_EXTENSIONS=ON -DLWS_WITH_MINIMAL_EXAMPLES=1"

View file

@ -13,18 +13,18 @@ The Travis build of lws done on every commit now runs
Tests|Count|Explanation
---|---|---
Build / Linux / gcc|13|-Wall -Werror cmake config variants
Build / Mac / Clang|13|-Wall -Werror cmake config variants
Build / Linux / gcc|14|-Wall -Werror cmake config variants
Build / Mac / Clang|14|-Wall -Werror cmake config variants
Build / Windows / MSVC|7|default
Selftests|33|minimal examples built and run against each other and remote server
Selftests|openssl:33, mbedtls:33|minimal examples built and run against each other and remote server
attack.sh|225|Correctness, robustness and security tests for http parser
Autobahn Server|480|Testing lws ws client, including permessage-deflate
Autobahn Client|480|Testing lws ws server, including permaessage-deflate
h2spec|146|Http/2 server compliance suite (in strict mode)
h2load|6|Http/2 server load tool (checks 10K / 100K in h1 and h2, at 1, 10, 100 concurrency)
h2spec|openssl:146, mbedtls:146|Http/2 server compliance suite (in strict mode)
h2load|openssl:6, mbedtls:6|Http/2 server load tool (checks 10K / 100K in h1 and h2, at 1, 10, 100 concurrency)
h2load SMP|6|Http/2 and http/1.1 server load checks on SMP server build
The over 1,400 tests run on every commit take most of an hour to complete.
The over 1,500 tests run on every commit take most of an hour to complete.
If any problems are found, it breaks the travis build, generating an email.
Current master passes all the tests and these new CI arrangements will help

View file

@ -54,10 +54,6 @@ const struct lws_event_loop_ops *available_event_libs[] = {
NULL
};
#if defined(LWS_WITH_TLS)
static char alpn_discovered[32];
#endif
static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH;
/**
@ -252,7 +248,7 @@ lws_protocol_init(struct lws_context *context)
}
#if defined(LWS_WITH_TLS)
any |= !!vh->ssl_ctx;
any |= !!vh->tls.ssl_ctx;
#endif
/*
@ -556,7 +552,7 @@ lws_create_vhost(struct lws_context *context,
struct lws_protocols *lwsp;
int m, f = !info->pvo;
char buf[20];
#ifdef LWS_HAVE_GETENV
#if !defined(LWS_WITHOUT_CLIENT) && defined(LWS_HAVE_GETENV)
char *p;
#endif
int n;
@ -599,7 +595,6 @@ lws_create_vhost(struct lws_context *context,
vh->pvo = info->pvo;
vh->headers = info->headers;
vh->user = info->user;
vh->alpn = info->alpn;
LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)
if (ar->init_vhost)
@ -607,7 +602,7 @@ lws_create_vhost(struct lws_context *context,
return NULL;
LWS_FOR_EVERY_AVAILABLE_ROLE_END;
vh->ssl_info_event_mask = info->ssl_info_event_mask;
if (info->keepalive_timeout)
vh->keepalive_timeout = info->keepalive_timeout;
else
@ -619,10 +614,13 @@ lws_create_vhost(struct lws_context *context,
vh->timeout_secs_ah_idle = 10;
#if defined(LWS_WITH_TLS)
vh->tls.alpn = info->alpn;
vh->tls.ssl_info_event_mask = info->ssl_info_event_mask;
if (info->ecdh_curve)
lws_strncpy(vh->ecdh_curve, info->ecdh_curve,
sizeof(vh->ecdh_curve));
#endif
lws_strncpy(vh->tls.ecdh_curve, info->ecdh_curve,
sizeof(vh->tls.ecdh_curve));
/* carefully allocate and take a copy of cert + key paths if present */
n = 0;
@ -632,16 +630,17 @@ lws_create_vhost(struct lws_context *context,
n += (int)strlen(info->ssl_private_key_filepath) + 1;
if (n) {
vh->key_path = vh->alloc_cert_path = lws_malloc(n, "vh paths");
vh->tls.key_path = vh->tls.alloc_cert_path = lws_malloc(n, "vh paths");
if (info->ssl_cert_filepath) {
n = (int)strlen(info->ssl_cert_filepath) + 1;
memcpy(vh->alloc_cert_path, info->ssl_cert_filepath, n);
vh->key_path += n;
memcpy(vh->tls.alloc_cert_path, info->ssl_cert_filepath, n);
vh->tls.key_path += n;
}
if (info->ssl_private_key_filepath)
memcpy(vh->key_path, info->ssl_private_key_filepath,
memcpy(vh->tls.key_path, info->ssl_private_key_filepath,
strlen(info->ssl_private_key_filepath) + 1);
}
#endif
/*
* give the vhost a unified list of protocols including the
@ -765,6 +764,7 @@ lws_create_vhost(struct lws_context *context,
vh->socks_proxy_address[0] = '\0';
#endif
#if !defined(LWS_WITHOUT_CLIENT)
/* either use proxy from info, or try get it from env var */
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
/* http proxy */
@ -782,6 +782,7 @@ lws_create_vhost(struct lws_context *context,
lws_set_proxy(vh, p);
#endif
}
#endif
#if defined(LWS_WITH_SOCKS5)
/* socks proxy */
if (info->socks_proxy_address) {
@ -990,6 +991,8 @@ lws_create_context(const struct lws_context_creation_info *info)
struct rlimit rt;
#endif
lwsl_info("Initial logging level %d\n", log_level);
lwsl_info("Libwebsockets version: %s\n", library_version);
#if defined(GCC_VER)
@ -1026,6 +1029,15 @@ lws_create_context(const struct lws_context_creation_info *info)
lwsl_err("No memory for websocket context\n");
return NULL;
}
#if defined(LWS_WITH_TLS)
#if defined(LWS_WITH_MBEDTLS)
context->tls_ops = &tls_ops_mbedtls;
#else
context->tls_ops = &tls_ops_openssl;
#endif
#endif
if (info->pt_serv_buf_size)
context->pt_serv_buf_size = info->pt_serv_buf_size;
else
@ -1152,25 +1164,26 @@ lws_create_context(const struct lws_context_creation_info *info)
#if defined(LWS_WITH_TLS)
if (info->alpn)
context->alpn_default = info->alpn;
context->tls.alpn_default = info->alpn;
else {
char *p = alpn_discovered, first = 1;
char *p = context->tls.alpn_discovered, first = 1;
LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) {
if (ar->alpn) {
if (!first)
*p++ = ',';
p += lws_snprintf(p, alpn_discovered +
sizeof(alpn_discovered) - 2 - p,
"%s", ar->alpn);
p += lws_snprintf(p,
context->tls.alpn_discovered +
sizeof(context->tls.alpn_discovered) -
2 - p, "%s", ar->alpn);
first = 0;
}
} LWS_FOR_EVERY_AVAILABLE_ROLE_END;
context->alpn_default = alpn_discovered;
context->tls.alpn_default = context->tls.alpn_discovered;
}
lwsl_info("Default ALPN advertisment: %s\n", context->alpn_default);
lwsl_info("Default ALPN advertisment: %s\n", context->tls.alpn_default);
#endif
if (info->timeout_secs)
@ -1616,7 +1629,9 @@ lws_vhost_destroy2(struct lws_vhost *vh)
close(vh->log_fd);
#endif
lws_free_set_NULL(vh->alloc_cert_path);
#if defined (LWS_WITH_TLS)
lws_free_set_NULL(vh->tls.alloc_cert_path);
#endif
#if LWS_MAX_SMP > 1
pthread_mutex_destroy(&vh->lock);

View file

@ -733,7 +733,7 @@ just_kill_connection:
!wsi->socket_is_permanently_unusable) {
#if defined(LWS_WITH_TLS)
if (lws_is_ssl(wsi) && wsi->ssl) {
if (lws_is_ssl(wsi) && wsi->tls.ssl) {
n = 0;
switch (__lws_tls_shutdown(wsi)) {
case LWS_SSL_CAPABLE_DONE:
@ -1703,6 +1703,7 @@ int user_callback_handle_rxflow(lws_callback_function callback_function,
return n;
}
#if !defined(LWS_WITHOUT_CLIENT)
LWS_VISIBLE int
lws_set_proxy(struct lws_vhost *vhost, const char *proxy)
{
@ -1761,6 +1762,7 @@ auth_too_long:
return -1;
}
#endif
#if defined(LWS_WITH_SOCKS5)
LWS_VISIBLE int
@ -2061,7 +2063,7 @@ LWS_VISIBLE int
lws_is_ssl(struct lws *wsi)
{
#if defined(LWS_WITH_TLS)
return wsi->use_ssl & LCCSCF_USE_SSL;
return wsi->tls.use_ssl & LCCSCF_USE_SSL;
#else
(void)wsi;
return 0;
@ -2072,7 +2074,7 @@ lws_is_ssl(struct lws *wsi)
LWS_VISIBLE lws_tls_conn*
lws_get_ssl(struct lws *wsi)
{
return wsi->ssl;
return wsi->tls.ssl;
}
#endif
@ -2974,7 +2976,7 @@ lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)
,
vh->name, vh->listen_port,
#if defined(LWS_WITH_TLS)
vh->use_ssl & LCCSCF_USE_SSL,
vh->tls.use_ssl & LCCSCF_USE_SSL,
#else
0,
#endif
@ -3304,10 +3306,9 @@ lws_stats_log_dump(struct lws_context *context)
(unsigned long long)(lws_stats_get(context,
LWSSTATS_MS_WRITABLE_DELAY) /
lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB)));
lwsl_notice("Simultaneous SSL restriction: %8d/%d/%d\n",
lwsl_notice("Simultaneous SSL restriction: %8d/%d\n",
context->simultaneous_ssl,
context->simultaneous_ssl_restriction,
context->ssl_gate_accepts);
context->simultaneous_ssl_restriction);
lwsl_notice("Live wsi: %8d\n",
context->count_wsi_allocated);

View file

@ -33,6 +33,9 @@ extern "C" {
#include <stdarg.h>
#endif
#include <string.h>
#include <stdlib.h>
#include "lws_config.h"
/*

View file

@ -217,16 +217,22 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
}
}
#if defined(LWS_WITH_TLS)
if (!pt->ws.rx_draining_ext_list &&
!lws_ssl_anybody_has_buffered_read_tsi(context, tsi) && !n) {
#else
if (!pt->ws.rx_draining_ext_list && !n) /* poll timeout */ {
m = 0;
#if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS)
m |= !!pt->ws.rx_draining_ext_list;
#endif
if (pt->context->tls_ops &&
pt->context->tls_ops->fake_POLLIN_for_buffered)
m |= pt->context->tls_ops->fake_POLLIN_for_buffered(pt);
if (!m && !n) {
lws_service_fd_tsi(context, NULL, tsi);
return 0;
}
faked_service:
m = lws_service_flag_pending(context, tsi);
if (m)
@ -1792,9 +1798,9 @@ lws_esp32_selfsigned(struct lws_vhost *vhost)
}
n = 0;
if (!nvs_get_blob(nvh, vhost->alloc_cert_path, NULL, &s))
if (!nvs_get_blob(nvh, vhost->tls.alloc_cert_path, NULL, &s))
n |= 1;
if (!nvs_get_blob(nvh, vhost->key_path, NULL, &s))
if (!nvs_get_blob(nvh, vhost->tls.key_path, NULL, &s))
n |= 2;
nvs_close(nvh);
@ -2041,7 +2047,7 @@ lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
const char *name = vhost->alloc_cert_path;
if (is_key)
name = vhost->key_path;
name = vhost->tls.key_path;
return lws_plat_write_file(name, buf, len) < 0;
}

View file

@ -137,19 +137,20 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
/* yes... come back again quickly */
timeout_ms = 0;
}
#if 1
n = poll(pt->fds, pt->fds_count, timeout_ms);
#if defined(LWS_WITH_TLS)
if (!pt->ws.rx_draining_ext_list &&
!lws_ssl_anybody_has_buffered_read_tsi(context, tsi) && !n) {
#else
if (!pt->ws.rx_draining_ext_list && !n) /* poll timeout */ {
#endif
m = 0;
if (pt->context->tls_ops &&
pt->context->tls_ops->fake_POLLIN_for_buffered)
m = pt->context->tls_ops->fake_POLLIN_for_buffered(pt);
if (/*!pt->ws.rx_draining_ext_list && */!m && !n) { /* nothing to do */
lws_service_fd_tsi(context, NULL, tsi);
return 0;
}
#endif
faked_service:
m = lws_service_flag_pending(context, tsi);
if (m)

View file

@ -257,15 +257,15 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
lws_pt_unlock(pt);
m = 0;
#if defined(LWS_WITH_TLS)
m |= !n && !lws_ssl_anybody_has_buffered_read_tsi(context, tsi);
#endif
#if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS)
m |= !n && !pt->ws.rx_draining_ext_list;
m |= !!pt->ws.rx_draining_ext_list;
#endif
if (m) {
if (pt->context->tls_ops &&
pt->context->tls_ops->fake_POLLIN_for_buffered)
m |= pt->context->tls_ops->fake_POLLIN_for_buffered(pt);
if (!m && !n) { /* nothing to do */
lws_service_fd_tsi(context, NULL, tsi);
lws_service_do_ripe_rxflow(pt);

View file

@ -262,6 +262,10 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
WSAResetEvent(pt->events[0]);
if (pt->context->tls_ops &&
pt->context->tls_ops->fake_POLLIN_for_buffered)
pt->context->tls_ops->fake_POLLIN_for_buffered(pt);
for (eIdx = 0; eIdx < pt->fds_count; ++eIdx) {
if (WSAEnumNetworkEvents(pt->fds[eIdx].fd, 0,
&networkevents) == SOCKET_ERROR) {
@ -302,7 +306,7 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
if (ev == WSA_WAIT_TIMEOUT)
lws_service_fd(context, NULL);
return 0;;
return 0;
}
LWS_VISIBLE int

View file

@ -199,9 +199,7 @@
#include "libwebsockets.h"
#if defined(LWS_WITH_TLS)
#include "tls/private.h"
#endif
#include "tls/private.h"
#if defined(WIN32) || defined(_WIN32)
#include <gettimeofday.h>
@ -548,7 +546,7 @@ struct lws_context_per_thread {
struct lws_dll_lws dll_head_buflist; /* guys with pending rxflow */
#if defined(LWS_WITH_TLS)
struct lws *pending_read_list; /* linked list */
struct lws_pt_tls tls;
#endif
struct lws_pollfd *fds;
@ -633,15 +631,11 @@ struct lws_timed_vh_protocol {
* SSL SNI -> wsi -> bind after SSL negotiation
*/
struct lws_tls_ss_pieces;
struct alpn_ctx {
uint8_t data[23];
uint8_t len;
};
struct lws_vhost {
#if !defined(LWS_WITHOUT_CLIENT)
char proxy_basic_auth_token[128];
#endif
#if LWS_MAX_SMP > 1
pthread_mutex_t lock;
#endif
@ -671,8 +665,7 @@ struct lws_vhost {
struct lws *lserv_wsi;
const char *name;
const char *iface;
char *alloc_cert_path;
char *key_path;
#if !defined(LWS_WITH_ESP32) && !defined(OPTEE_TA) && !defined(WIN32)
int bind_iface;
#endif
@ -686,16 +679,8 @@ struct lws_vhost {
struct lws_dll_lws dll_active_client_conns;
#endif
const char *alpn;
#if defined(LWS_WITH_TLS)
lws_tls_ctx *ssl_ctx;
lws_tls_ctx *ssl_client_ctx;
struct lws_tls_ss_pieces *ss; /* for acme tls certs */
char ecdh_curve[16];
struct alpn_ctx alpn_ctx;
#endif
#if defined(LWS_WITH_MBEDTLS)
lws_tls_x509 *x509_client_CA;
struct lws_vhost_tls tls;
#endif
struct lws_timed_vh_protocol *timed_vh_protocol_list;
@ -713,21 +698,13 @@ struct lws_vhost {
int ka_interval;
int keepalive_timeout;
int timeout_secs_ah_idle;
int ssl_info_event_mask;
#ifdef LWS_WITH_ACCESS_LOG
int log_fd;
#endif
#if defined(LWS_WITH_TLS)
int use_ssl;
int allow_non_ssl_on_ssl_port;
unsigned int user_supplied_ssl_ctx:1;
#endif
unsigned int created_vhost_protocols:1;
unsigned int being_destroyed:1;
unsigned int skipped_certs:1;
unsigned int acme_challenge:1;
unsigned char default_protocol_index;
unsigned char raw_protocol_index;
@ -786,6 +763,9 @@ struct lws_context {
const struct lws_plat_file_ops *fops;
struct lws_plat_file_ops fops_platform;
struct lws_context **pcontext_finalize;
const struct lws_tls_ops *tls_ops;
#if defined(LWS_WITH_HTTP2)
struct http2_settings set;
#endif
@ -818,9 +798,7 @@ struct lws_context {
void *external_baggage_free_on_destroy;
const struct lws_token_limits *token_limits;
void *user_space;
const char *server_string;
const struct lws_protocol_vhost_options *reject_service_keywords;
const char *alpn_default;
lws_reload_func deprecation_cb;
void (*eventlib_signal_cb)(void *event_lib_handle, int signum);
@ -841,7 +819,13 @@ struct lws_context {
struct lws_event_loop_ops *event_loop_ops;
#if defined(LWS_WITH_TLS)
struct lws_context_tls tls;
#endif
char canonical_hostname[128];
const char *server_string;
#ifdef LWS_LATENCY
unsigned long worst_latency;
char worst_latency_info[256];
@ -885,7 +869,6 @@ struct lws_context {
unsigned int being_destroyed2:1;
unsigned int requested_kill:1;
unsigned int protocol_init_done:1;
unsigned int ssl_gate_accepts:1;
unsigned int doing_protocol_init:1;
unsigned int done_protocol_destroy_cb:1;
unsigned int finalize_destroy_after_internal_loops_stopped:1;
@ -1014,6 +997,7 @@ struct lws_buflist {
#define LWS_H2_FRAME_HEADER_LENGTH 9
struct lws {
/* structs */
@ -1027,7 +1011,7 @@ struct lws {
struct _lws_websocket_related *ws; /* allocated if we upgrade to ws */
#endif
struct lws_role_ops *role_ops;
const struct lws_role_ops *role_ops;
lws_wsi_state_t wsistate;
lws_wsi_state_t wsistate_pre_close;
@ -1076,9 +1060,7 @@ struct lws {
unsigned char *trunc_alloc; /* non-NULL means buffering in progress */
#if defined(LWS_WITH_TLS)
lws_tls_conn *ssl;
lws_tls_bio *client_bio;
struct lws *pending_read_list_prev, *pending_read_list_next;
struct lws_lws_tls tls;
#endif
#ifdef LWS_LATENCY
@ -1097,8 +1079,6 @@ struct lws {
lws_usec_t pending_timer;
time_t pending_timeout_set;
/* ints */
int position_in_fds_table;
unsigned int trunc_alloc_len; /* size of malloc */
@ -1160,10 +1140,6 @@ struct lws {
unsigned int client_h2_substream:1;
#endif
#if defined(LWS_WITH_TLS)
unsigned int use_ssl;
unsigned int redirect_to_https:1;
#endif
#ifdef _WIN32
unsigned int sock_send_blocking:1;
#endif
@ -1426,7 +1402,6 @@ LWS_EXTERN void lwsl_emit_stderr(int level, const char *line);
#define lws_ssl_remove_wsi_from_buffered_list(_a)
#define __lws_ssl_remove_wsi_from_buffered_list(_a)
#define lws_context_init_ssl_library(_a)
#define lws_ssl_anybody_has_buffered_read_tsi(_a, _b) (0)
#define lws_tls_check_all_cert_lifetimes(_a)
#define lws_tls_acme_sni_cert_destroy(_a)
#endif

View file

@ -469,7 +469,6 @@ try_pollout:
fail:
lwsl_notice("%s: fail: closing\n", __func__);
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "server socket svc fail");
return LWS_HPI_RET_WSI_ALREADY_DIED;

View file

@ -90,8 +90,8 @@ lws_client_connect_2(struct lws *wsi)
if (w != wsi && w->client_hostname_copy &&
!strcmp(adsin, w->client_hostname_copy) &&
#if defined(LWS_WITH_TLS)
(wsi->use_ssl & LCCSCF_USE_SSL) ==
(w->use_ssl & LCCSCF_USE_SSL) &&
(wsi->tls.use_ssl & LCCSCF_USE_SSL) ==
(w->tls.use_ssl & LCCSCF_USE_SSL) &&
#endif
wsi->c_port == w->c_port) {
@ -658,7 +658,7 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
__remove_wsi_socket_from_fds(wsi);
#if defined(LWS_WITH_TLS)
wsi->use_ssl = ssl;
wsi->tls.use_ssl = ssl;
#else
if (ssl) {
lwsl_err("%s: not configured for ssl\n", __func__);
@ -971,7 +971,7 @@ lws_client_connect_via_info(struct lws_client_connect_info *i)
goto bail;
#if defined(LWS_WITH_TLS)
wsi->use_ssl = i->ssl_connection;
wsi->tls.use_ssl = i->ssl_connection;
#else
if (i->ssl_connection & LCCSCF_USE_SSL) {
lwsl_err("libwebsockets not configured for ssl\n");

View file

@ -309,13 +309,13 @@ start_ws_handshake:
#if defined(LWS_WITH_TLS)
/* we can retry this... just cook the SSL BIO the first time */
if ((wsi->use_ssl & LCCSCF_USE_SSL) && !wsi->ssl &&
if ((wsi->tls.use_ssl & LCCSCF_USE_SSL) && !wsi->tls.ssl &&
lws_ssl_client_bio_create(wsi) < 0) {
cce = "bio_create failed";
goto bail3;
}
if (wsi->use_ssl & LCCSCF_USE_SSL) {
if (wsi->tls.use_ssl & LCCSCF_USE_SSL) {
n = lws_ssl_client_connect1(wsi);
if (!n)
return 0;
@ -324,13 +324,13 @@ start_ws_handshake:
goto bail3;
}
} else
wsi->ssl = NULL;
wsi->tls.ssl = NULL;
/* fallthru */
case LRS_WAITING_SSL:
if (wsi->use_ssl & LCCSCF_USE_SSL) {
if (wsi->tls.use_ssl & LCCSCF_USE_SSL) {
n = lws_ssl_client_connect2(wsi, ebuf, sizeof(ebuf));
if (!n)
return 0;
@ -339,7 +339,7 @@ start_ws_handshake:
goto bail3;
}
} else
wsi->ssl = NULL;
wsi->tls.ssl = NULL;
#endif
#if defined (LWS_WITH_HTTP2)
if (wsi->client_h2_alpn) {
@ -746,7 +746,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
/* Relative reference absolute path */
if (p[0] == '/') {
#if defined(LWS_WITH_TLS)
ssl = wsi->use_ssl & LCCSCF_USE_SSL;
ssl = wsi->tls.use_ssl & LCCSCF_USE_SSL;
#endif
ads = lws_hdr_simple_ptr(wsi,
_WSI_TOKEN_CLIENT_PEER_ADDRESS);
@ -769,7 +769,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
/* This doesn't try to calculate an absolute path,
* that will be left to the server */
#if defined(LWS_WITH_TLS)
ssl = wsi->use_ssl & LCCSCF_USE_SSL;
ssl = wsi->tls.use_ssl & LCCSCF_USE_SSL;
#endif
ads = lws_hdr_simple_ptr(wsi,
_WSI_TOKEN_CLIENT_PEER_ADDRESS);
@ -787,7 +787,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
}
#if defined(LWS_WITH_TLS)
if ((wsi->use_ssl & LCCSCF_USE_SSL) && !ssl) {
if ((wsi->tls.use_ssl & LCCSCF_USE_SSL) && !ssl) {
cce = "HS: Redirect attempted SSL downgrade";
goto bail3;
}

View file

@ -952,7 +952,7 @@ lws_http_action(struct lws *wsi)
lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
wsi->context->timeout_secs);
#ifdef LWS_WITH_TLS
if (wsi->redirect_to_https) {
if (wsi->tls.redirect_to_https) {
/*
* we accepted http:// only so we could redirect to
* https://, so issue the redirect. Create the redirection
@ -1681,7 +1681,7 @@ lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi)
new_wsi->hdr_parsing_completed = 0;
#ifdef LWS_WITH_TLS
new_wsi->use_ssl = LWS_SSL_ENABLED(vhost);
new_wsi->tls.use_ssl = LWS_SSL_ENABLED(vhost);
#endif
/*
@ -1779,7 +1779,7 @@ lws_http_transaction_completed(struct lws *wsi)
* SSL is scarce, drop this connection without waiting
*/
if (wsi->vhost->use_ssl &&
if (wsi->vhost->tls.use_ssl &&
wsi->context->simultaneous_ssl_restriction &&
wsi->context->simultaneous_ssl ==
wsi->context->simultaneous_ssl_restriction) {

View file

@ -51,7 +51,7 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
* another vhost may also have had POLLIN on his
* listener this round and used it up already
*/
if (wsi->vhost->use_ssl &&
if (wsi->vhost->tls.use_ssl &&
context->simultaneous_ssl_restriction &&
context->simultaneous_ssl ==
context->simultaneous_ssl_restriction)

View file

@ -791,7 +791,7 @@ lws_server_init_wsi_for_ws(struct lws *wsi)
if (wsi->protocol->callback(wsi, LWS_CALLBACK_ESTABLISHED,
wsi->user_space,
#ifdef LWS_WITH_TLS
wsi->ssl,
wsi->tls.ssl,
#else
NULL,
#endif

View file

@ -328,13 +328,12 @@ lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi)
return 0;
#endif
#if defined(LWS_WITH_TLS)
/* 2) if we know we have non-network pending data, do not wait in poll */
if (lws_ssl_anybody_has_buffered_read_tsi(context, tsi)) {
lwsl_info("ssl buffered read\n");
return 0;
}
#endif
if (pt->context->tls_ops &&
pt->context->tls_ops->fake_POLLIN_for_buffered)
if (pt->context->tls_ops->fake_POLLIN_for_buffered(pt))
return 0;
/* 3) If there is any wsi with rxflow buffered and in a state to process
* it, we should not wait in poll
@ -521,9 +520,9 @@ lws_service_flag_pending(struct lws_context *context, int tsi)
* service to use up the buffered incoming data, even though their
* network socket may have nothing
*/
wsi = pt->pending_read_list;
wsi = pt->tls.pending_read_list;
while (wsi) {
wsi_next = wsi->pending_read_list_next;
wsi_next = wsi->tls.pending_read_list_next;
pt->fds[wsi->position_in_fds_table].revents |=
pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN;
if (pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN) {
@ -870,7 +869,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,
}
#if defined(LWS_WITH_TLS)
if (lwsi_state(wsi) == LRS_SHUTDOWN && lws_is_ssl(wsi) && wsi->ssl) {
if (lwsi_state(wsi) == LRS_SHUTDOWN && lws_is_ssl(wsi) && wsi->tls.ssl) {
switch (__lws_tls_shutdown(wsi)) {
case LWS_SSL_CAPABLE_DONE:
case LWS_SSL_CAPABLE_ERROR:

View file

@ -32,7 +32,7 @@ lws_ssl_client_bio_create(struct lws *wsi)
{
X509_VERIFY_PARAM *param;
char hostname[128], *p;
const char *alpn_comma = wsi->context->alpn_default;
const char *alpn_comma = wsi->context->tls.alpn_default;
struct alpn_ctx protos;
if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
@ -55,23 +55,23 @@ lws_ssl_client_bio_create(struct lws *wsi)
p++;
}
wsi->ssl = SSL_new(wsi->vhost->ssl_client_ctx);
if (!wsi->ssl)
wsi->tls.ssl = SSL_new(wsi->vhost->tls.ssl_client_ctx);
if (!wsi->tls.ssl)
return -1;
if (wsi->vhost->ssl_info_event_mask)
SSL_set_info_callback(wsi->ssl, lws_ssl_info_callback);
if (wsi->vhost->tls.ssl_info_event_mask)
SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback);
if (!(wsi->use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
param = SSL_get0_param(wsi->ssl);
if (!(wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
param = SSL_get0_param(wsi->tls.ssl);
/* Enable automatic hostname checks */
// X509_VERIFY_PARAM_set_hostflags(param,
// X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
X509_VERIFY_PARAM_set1_host(param, hostname, 0);
}
if (wsi->vhost->alpn)
alpn_comma = wsi->vhost->alpn;
if (wsi->vhost->tls.alpn)
alpn_comma = wsi->vhost->tls.alpn;
if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
_WSI_TOKEN_CLIENT_ALPN) > 0)
@ -84,16 +84,16 @@ lws_ssl_client_bio_create(struct lws *wsi)
sizeof(protos.data) - 1);
/* with mbedtls, protos is not pointed to after exit from this call */
SSL_set_alpn_select_cb(wsi->ssl, &protos);
SSL_set_alpn_select_cb(wsi->tls.ssl, &protos);
/*
* use server name indication (SNI), if supported,
* when establishing connection
*/
SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER,
SSL_set_verify(wsi->tls.ssl, SSL_VERIFY_PEER,
OpenSSL_client_verify_callback);
SSL_set_fd(wsi->ssl, wsi->desc.sockfd);
SSL_set_fd(wsi->tls.ssl, wsi->desc.sockfd);
return 0;
}
@ -106,23 +106,23 @@ int ERR_get_error(void)
enum lws_ssl_capable_status
lws_tls_client_connect(struct lws *wsi)
{
int m, n = SSL_connect(wsi->ssl);
int m, n = SSL_connect(wsi->tls.ssl);
const unsigned char *prot;
unsigned int len;
if (n == 1) {
SSL_get0_alpn_selected(wsi->ssl, &prot, &len);
SSL_get0_alpn_selected(wsi->tls.ssl, &prot, &len);
lws_role_call_alpn_negotiated(wsi, (const char *)prot);
lwsl_info("client connect OK\n");
return LWS_SSL_CAPABLE_DONE;
}
m = SSL_get_error(wsi->ssl, n);
m = SSL_get_error(wsi->tls.ssl, n);
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl))
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl))
return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl))
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl))
return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
if (!n) /* we don't know what he wants, but he says to retry */
@ -135,7 +135,7 @@ int
lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len)
{
int n;
X509 *peer = SSL_get_peer_certificate(wsi->ssl);
X509 *peer = SSL_get_peer_certificate(wsi->tls.ssl);
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
char *sb = (char *)&pt->serv_buf[0];
@ -146,7 +146,7 @@ lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len)
}
lwsl_info("peer provided cert\n");
n = SSL_get_verify_result(wsi->ssl);
n = SSL_get_verify_result(wsi->tls.ssl);
lws_latency(wsi->context, wsi,
"SSL_get_verify_result LWS_CONNMODE..HANDSHAKE", n, n > 0);
@ -156,20 +156,20 @@ lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len)
return 0;
if (n == X509_V_ERR_HOSTNAME_MISMATCH &&
(wsi->use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
(wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
lwsl_info("accepting certificate for invalid hostname\n");
return 0;
}
if (n == X509_V_ERR_INVALID_CA &&
(wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED)) {
(wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED)) {
lwsl_info("accepting certificate from untrusted CA\n");
return 0;
}
if ((n == X509_V_ERR_CERT_NOT_YET_VALID ||
n == X509_V_ERR_CERT_HAS_EXPIRED) &&
(wsi->use_ssl & LCCSCF_ALLOW_EXPIRED)) {
(wsi->tls.use_ssl & LCCSCF_ALLOW_EXPIRED)) {
lwsl_info("accepting expired or not yet valid certificate\n");
return 0;
@ -205,8 +205,8 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
return 1;
}
/* create context */
vh->ssl_client_ctx = SSL_CTX_new(method);
if (!vh->ssl_client_ctx) {
vh->tls.ssl_client_ctx = SSL_CTX_new(method);
if (!vh->tls.ssl_client_ctx) {
error = ERR_get_error();
lwsl_err("problem creating ssl context %lu: %s\n",
error, ERR_error_string(error,
@ -222,17 +222,17 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
return 1;
}
vh->x509_client_CA = d2i_X509(NULL, buf, len);
vh->tls.x509_client_CA = d2i_X509(NULL, buf, len);
free(buf);
if (!vh->x509_client_CA) {
if (!vh->tls.x509_client_CA) {
lwsl_err("client CA: x509 parse failed\n");
return 1;
}
if (!vh->ssl_ctx)
SSL_CTX_add_client_CA(vh->ssl_client_ctx, vh->x509_client_CA);
if (!vh->tls.ssl_ctx)
SSL_CTX_add_client_CA(vh->tls.ssl_client_ctx, vh->tls.x509_client_CA);
else
SSL_CTX_add_client_CA(vh->ssl_ctx, vh->x509_client_CA);
SSL_CTX_add_client_CA(vh->tls.ssl_ctx, vh->tls.x509_client_CA);
lwsl_notice("client loaded CA for verification %s\n", ca_filepath);

View file

@ -48,7 +48,7 @@ lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)
lwsl_notice("%s: vh %s requires client cert %d\n", __func__, vh->name,
verify_options);
SSL_CTX_set_verify(vh->ssl_ctx, verify_options, NULL);
SSL_CTX_set_verify(vh->tls.ssl_ctx, verify_options, NULL);
return 0;
}
@ -71,7 +71,7 @@ lws_mbedtls_sni_cb(void *arg, mbedtls_ssl_context *mbedtls_ctx,
vh = context->vhost_list;
while (vh) {
if (!vh->being_destroyed &&
vh->ssl_ctx == SSL_get_SSL_CTX(ssl))
vh->tls.ssl_ctx == SSL_get_SSL_CTX(ssl))
break;
vh = vh->vhost_next;
}
@ -93,7 +93,7 @@ lws_mbedtls_sni_cb(void *arg, mbedtls_ssl_context *mbedtls_ctx,
vh->listen_port, vhost->name);
/* select the ssl ctx from the selected vhost for this conn */
SSL_set_SSL_CTX(ssl, vhost->ssl_ctx);
SSL_set_SSL_CTX(ssl, vhost->tls.ssl_ctx);
return 0;
}
@ -158,7 +158,7 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
}
f = 1;
}
err = SSL_CTX_use_certificate_ASN1(vhost->ssl_ctx, flen, p);
err = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx, flen, p);
if (!err) {
free(p);
lwsl_err("Problem loading cert\n");
@ -178,7 +178,7 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
return 1;
}
err = SSL_CTX_use_PrivateKey_ASN1(0, vhost->ssl_ctx, p, flen);
err = SSL_CTX_use_PrivateKey_ASN1(0, vhost->tls.ssl_ctx, p, flen);
if (!err) {
free(p);
lwsl_err("Problem loading key\n");
@ -195,13 +195,13 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
if (!private_key && !mem_privkey &&
vhost->protocols[0].callback(wsi,
LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
vhost->ssl_ctx, NULL, 0)) {
vhost->tls.ssl_ctx, NULL, 0)) {
lwsl_err("ssl private key not set\n");
return 1;
}
vhost->skipped_certs = 0;
vhost->tls.skipped_certs = 0;
return 0;
}
@ -215,13 +215,13 @@ lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info,
lws_filepos_t flen;
int n;
vhost->ssl_ctx = SSL_CTX_new(method); /* create context */
if (!vhost->ssl_ctx) {
vhost->tls.ssl_ctx = SSL_CTX_new(method); /* create context */
if (!vhost->tls.ssl_ctx) {
lwsl_err("problem creating ssl context\n");
return 1;
}
if (!vhost->use_ssl || !info->ssl_cert_filepath)
if (!vhost->tls.use_ssl || !info->ssl_cert_filepath)
return 0;
if (info->ssl_ca_filepath) {
@ -235,7 +235,7 @@ lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info,
return 1;
}
if (SSL_CTX_add_client_CA_ASN1(vhost->ssl_ctx, (int)flen, p) != 1) {
if (SSL_CTX_add_client_CA_ASN1(vhost->tls.ssl_ctx, (int)flen, p) != 1) {
lwsl_err("%s: SSL_CTX_add_client_CA_ASN1 unhappy\n",
__func__);
free(p);
@ -257,20 +257,20 @@ int
lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd)
{
errno = 0;
wsi->ssl = SSL_new(wsi->vhost->ssl_ctx);
if (wsi->ssl == NULL) {
wsi->tls.ssl = SSL_new(wsi->vhost->tls.ssl_ctx);
if (wsi->tls.ssl == NULL) {
lwsl_err("SSL_new failed: errno %d\n", errno);
lws_ssl_elaborate_error();
return 1;
}
SSL_set_fd(wsi->ssl, accept_fd);
SSL_set_fd(wsi->tls.ssl, accept_fd);
if (wsi->vhost->ssl_info_event_mask)
SSL_set_info_callback(wsi->ssl, lws_ssl_info_callback);
if (wsi->vhost->tls.ssl_info_event_mask)
SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback);
SSL_set_sni_callback(wsi->ssl, lws_mbedtls_sni_cb, wsi->context);
SSL_set_sni_callback(wsi->tls.ssl, lws_mbedtls_sni_cb, wsi->context);
return 0;
}
@ -279,7 +279,7 @@ int
lws_tls_server_abort_connection(struct lws *wsi)
{
__lws_tls_shutdown(wsi);
SSL_free(wsi->ssl);
SSL_free(wsi->tls.ssl);
return 0;
}
@ -290,7 +290,7 @@ lws_tls_server_accept(struct lws *wsi)
union lws_tls_cert_info_results ir;
int m, n;
n = SSL_accept(wsi->ssl);
n = SSL_accept(wsi->tls.ssl);
if (n == 1) {
if (strstr(wsi->vhost->name, ".invalid")) {
@ -309,7 +309,7 @@ lws_tls_server_accept(struct lws *wsi)
return LWS_SSL_CAPABLE_DONE;
}
m = SSL_get_error(wsi->ssl, n);
m = SSL_get_error(wsi->tls.ssl, n);
lwsl_debug("%s: %p: accept SSL_get_error %d errno %d\n", __func__,
wsi, m, errno);
@ -320,7 +320,7 @@ lws_tls_server_accept(struct lws *wsi)
if (m == SSL_ERROR_SYSCALL || m == SSL_ERROR_SSL)
return LWS_SSL_CAPABLE_ERROR;
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl)) {
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
lwsl_info("%s: WANT_READ change_pollfd failed\n", __func__);
return LWS_SSL_CAPABLE_ERROR;
@ -329,7 +329,7 @@ lws_tls_server_accept(struct lws *wsi)
lwsl_info("SSL_ERROR_WANT_READ\n");
return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
}
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) {
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
lwsl_debug("%s: WANT_WRITE\n", __func__);
if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
@ -543,7 +543,7 @@ lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
}
// lwsl_hexdump_level(LLL_DEBUG, buf, lws_ptr_diff(p, buf));
n = SSL_CTX_use_certificate_ASN1(vhost->ssl_ctx,
n = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx,
lws_ptr_diff(p, buf), buf);
if (n != 1) {
lws_free(pkey_asn1);
@ -554,7 +554,7 @@ lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
//lwsl_hexdump_level(LLL_DEBUG, pkey_asn1, n);
/* and to use our generated private key */
n = SSL_CTX_use_PrivateKey_ASN1(0, vhost->ssl_ctx, pkey_asn1, m);
n = SSL_CTX_use_PrivateKey_ASN1(0, vhost->tls.ssl_ctx, pkey_asn1, m);
lws_free(pkey_asn1);
if (n != 1) {
lwsl_err("%s: SSL_CTX_use_PrivateKey_ASN1 failed\n",

View file

@ -45,13 +45,13 @@ lws_ssl_destroy(struct lws_vhost *vhost)
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
return;
if (vhost->ssl_ctx)
SSL_CTX_free(vhost->ssl_ctx);
if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
SSL_CTX_free(vhost->ssl_client_ctx);
if (vhost->tls.ssl_ctx)
SSL_CTX_free(vhost->tls.ssl_ctx);
if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx)
SSL_CTX_free(vhost->tls.ssl_client_ctx);
if (vhost->x509_client_CA)
X509_free(vhost->x509_client_CA);
if (vhost->tls.x509_client_CA)
X509_free(vhost->tls.x509_client_CA);
}
LWS_VISIBLE int
@ -61,13 +61,13 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
int n = 0, m;
if (!wsi->ssl)
if (!wsi->tls.ssl)
return lws_ssl_capable_read_no_ssl(wsi, buf, len);
lws_stats_atomic_bump(context, pt, LWSSTATS_C_API_READ, 1);
errno = 0;
n = SSL_read(wsi->ssl, buf, len);
n = SSL_read(wsi->tls.ssl, buf, len);
#if defined(LWS_WITH_ESP32)
if (!n && errno == ENOTCONN) {
lwsl_debug("%p: SSL_read ENOTCONN\n", wsi);
@ -95,18 +95,18 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
}
if (n < 0) {
m = SSL_get_error(wsi->ssl, n);
m = SSL_get_error(wsi->tls.ssl, n);
lwsl_debug("%p: ssl err %d errno %d\n", wsi, m, errno);
if (m == SSL_ERROR_ZERO_RETURN ||
m == SSL_ERROR_SYSCALL)
return LWS_SSL_CAPABLE_ERROR;
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl)) {
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
lwsl_debug("%s: WANT_READ\n", __func__);
lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi);
return LWS_SSL_CAPABLE_MORE_SERVICE;
}
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) {
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
lwsl_debug("%s: WANT_WRITE\n", __func__);
lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi);
return LWS_SSL_CAPABLE_MORE_SERVICE;
@ -132,26 +132,26 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
*/
if (n != len)
goto bail;
if (!wsi->ssl)
if (!wsi->tls.ssl)
goto bail;
if (!SSL_pending(wsi->ssl))
if (!SSL_pending(wsi->tls.ssl))
goto bail;
if (wsi->pending_read_list_next)
if (wsi->tls.pending_read_list_next)
return n;
if (wsi->pending_read_list_prev)
if (wsi->tls.pending_read_list_prev)
return n;
if (pt->pending_read_list == wsi)
if (pt->tls.pending_read_list == wsi)
return n;
/* add us to the linked list of guys with pending ssl */
if (pt->pending_read_list)
pt->pending_read_list->pending_read_list_prev = wsi;
if (pt->tls.pending_read_list)
pt->tls.pending_read_list->tls.pending_read_list_prev = wsi;
wsi->pending_read_list_next = pt->pending_read_list;
wsi->pending_read_list_prev = NULL;
pt->pending_read_list = wsi;
wsi->tls.pending_read_list_next = pt->tls.pending_read_list;
wsi->tls.pending_read_list_prev = NULL;
pt->tls.pending_read_list = wsi;
return n;
bail:
@ -163,10 +163,10 @@ bail:
LWS_VISIBLE int
lws_ssl_pending(struct lws *wsi)
{
if (!wsi->ssl)
if (!wsi->tls.ssl)
return 0;
return SSL_pending(wsi->ssl);
return SSL_pending(wsi->tls.ssl);
}
LWS_VISIBLE int
@ -174,22 +174,22 @@ lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
{
int n, m;
if (!wsi->ssl)
if (!wsi->tls.ssl)
return lws_ssl_capable_write_no_ssl(wsi, buf, len);
n = SSL_write(wsi->ssl, buf, len);
n = SSL_write(wsi->tls.ssl, buf, len);
if (n > 0)
return n;
m = SSL_get_error(wsi->ssl, n);
m = SSL_get_error(wsi->tls.ssl, n);
if (m != SSL_ERROR_SYSCALL) {
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl)) {
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
lwsl_notice("%s: want read\n", __func__);
return LWS_SSL_CAPABLE_MORE_SERVICE;
}
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) {
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
lws_set_blocking_send(wsi);
lwsl_notice("%s: want write\n", __func__);
@ -221,7 +221,7 @@ lws_ssl_info_callback(const SSL *ssl, int where, int ret)
if (!wsi)
return;
if (!(where & wsi->vhost->ssl_info_event_mask))
if (!(where & wsi->vhost->tls.ssl_info_event_mask))
return;
si.where = where;
@ -239,23 +239,23 @@ lws_ssl_close(struct lws *wsi)
{
lws_sockfd_type n;
if (!wsi->ssl)
if (!wsi->tls.ssl)
return 0; /* not handled */
#if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
/* kill ssl callbacks, becausse we will remove the fd from the
* table linking it to the wsi
*/
if (wsi->vhost->ssl_info_event_mask)
SSL_set_info_callback(wsi->ssl, NULL);
if (wsi->vhost->tls.ssl_info_event_mask)
SSL_set_info_callback(wsi->tls.ssl, NULL);
#endif
n = SSL_get_fd(wsi->ssl);
n = SSL_get_fd(wsi->tls.ssl);
if (!wsi->socket_is_permanently_unusable)
SSL_shutdown(wsi->ssl);
SSL_shutdown(wsi->tls.ssl);
compatible_close(n);
SSL_free(wsi->ssl);
wsi->ssl = NULL;
SSL_free(wsi->tls.ssl);
wsi->tls.ssl = NULL;
if (!lwsi_role_client(wsi) &&
wsi->context->simultaneous_ssl_restriction &&
@ -274,11 +274,11 @@ lws_ssl_close(struct lws *wsi)
void
lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
{
if (vhost->ssl_ctx)
SSL_CTX_free(vhost->ssl_ctx);
if (vhost->tls.ssl_ctx)
SSL_CTX_free(vhost->tls.ssl_ctx);
if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
SSL_CTX_free(vhost->ssl_client_ctx);
if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx)
SSL_CTX_free(vhost->tls.ssl_client_ctx);
#if defined(LWS_WITH_ACME)
lws_tls_acme_sni_cert_destroy(vhost);
#endif
@ -292,16 +292,16 @@ lws_ssl_context_destroy(struct lws_context *context)
lws_tls_ctx *
lws_tls_ctx_from_wsi(struct lws *wsi)
{
if (!wsi->ssl)
if (!wsi->tls.ssl)
return NULL;
return SSL_get_SSL_CTX(wsi->ssl);
return SSL_get_SSL_CTX(wsi->tls.ssl);
}
enum lws_ssl_capable_status
__lws_tls_shutdown(struct lws *wsi)
{
int n = SSL_shutdown(wsi->ssl);
int n = SSL_shutdown(wsi->tls.ssl);
lwsl_debug("SSL_shutdown=%d for fd %d\n", n, wsi->desc.sockfd);
@ -315,14 +315,14 @@ __lws_tls_shutdown(struct lws *wsi)
return LWS_SSL_CAPABLE_MORE_SERVICE;
default: /* fatal error, or WANT */
n = SSL_get_error(wsi->ssl, n);
n = SSL_get_error(wsi->tls.ssl, n);
if (n != SSL_ERROR_SYSCALL && n != SSL_ERROR_SSL) {
if (SSL_want_read(wsi->ssl)) {
if (SSL_want_read(wsi->tls.ssl)) {
lwsl_debug("(wants read)\n");
__lws_change_pollfd(wsi, 0, LWS_POLLIN);
return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
}
if (SSL_want_write(wsi->ssl)) {
if (SSL_want_write(wsi->tls.ssl)) {
lwsl_debug("(wants write)\n");
__lws_change_pollfd(wsi, 0, LWS_POLLOUT);
return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
@ -466,7 +466,7 @@ LWS_VISIBLE LWS_EXTERN int
lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
union lws_tls_cert_info_results *buf, size_t len)
{
mbedtls_x509_crt *x509 = ssl_ctx_get_mbedtls_x509_crt(vhost->ssl_ctx);
mbedtls_x509_crt *x509 = ssl_ctx_get_mbedtls_x509_crt(vhost->tls.ssl_ctx);
return lws_tls_mbedtls_cert_info(x509, type, buf, len);
}
@ -479,14 +479,14 @@ lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
wsi = lws_get_network_wsi(wsi);
x509 = ssl_get_peer_mbedtls_x509_crt(wsi->ssl);
x509 = ssl_get_peer_mbedtls_x509_crt(wsi->tls.ssl);
if (!x509)
return -1;
switch (type) {
case LWS_TLS_CERT_INFO_VERIFIED:
buf->verified = SSL_get_verify_result(wsi->ssl) == X509_V_OK;
buf->verified = SSL_get_verify_result(wsi->tls.ssl) == X509_V_OK;
return 0;
default:
return lws_tls_mbedtls_cert_info(x509, type, buf, len);
@ -494,3 +494,14 @@ lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
return -1;
}
static int
tops_fake_POLLIN_for_buffered_mbedtls(struct lws_context_per_thread *pt)
{
return lws_tls_fake_POLLIN_for_buffered(pt);
}
const struct lws_tls_ops tls_ops_mbedtls = {
/* fake_POLLIN_for_buffered */ tops_fake_POLLIN_for_buffered_mbedtls,
};

View file

@ -43,13 +43,13 @@ OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
if ((err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED) {
wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED) {
lwsl_notice("accepting self-signed certificate (verify_callback)\n");
X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
return 1; // ok
} else if ((err == X509_V_ERR_CERT_NOT_YET_VALID ||
err == X509_V_ERR_CERT_HAS_EXPIRED) &&
wsi->use_ssl & LCCSCF_ALLOW_EXPIRED) {
wsi->tls.use_ssl & LCCSCF_ALLOW_EXPIRED) {
if (err == X509_V_ERR_CERT_NOT_YET_VALID)
lwsl_notice("accepting not yet valid certificate (verify_callback)\n");
else if (err == X509_V_ERR_CERT_HAS_EXPIRED)
@ -97,7 +97,7 @@ lws_ssl_client_bio_create(struct lws *wsi)
#if defined(LWS_HAVE_SSL_set_alpn_protos) && \
defined(LWS_HAVE_SSL_get0_alpn_selected)
uint8_t openssl_alpn[40];
const char *alpn_comma = wsi->context->alpn_default;
const char *alpn_comma = wsi->context->tls.alpn_default;
int n;
#endif
@ -124,8 +124,8 @@ lws_ssl_client_bio_create(struct lws *wsi)
p++;
}
wsi->ssl = SSL_new(wsi->vhost->ssl_client_ctx);
if (!wsi->ssl) {
wsi->tls.ssl = SSL_new(wsi->vhost->tls.ssl_client_ctx);
if (!wsi->tls.ssl) {
lwsl_err("SSL_new failed: %s\n",
ERR_error_string(lws_ssl_get_error(wsi, 0), NULL));
lws_ssl_elaborate_error();
@ -133,13 +133,13 @@ lws_ssl_client_bio_create(struct lws *wsi)
}
#if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
if (wsi->vhost->ssl_info_event_mask)
SSL_set_info_callback(wsi->ssl, lws_ssl_info_callback);
if (wsi->vhost->tls.ssl_info_event_mask)
SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback);
#endif
#if defined LWS_HAVE_X509_VERIFY_PARAM_set1_host
if (!(wsi->use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
param = SSL_get0_param(wsi->ssl);
if (!(wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
param = SSL_get0_param(wsi->tls.ssl);
/* Enable automatic hostname checks */
X509_VERIFY_PARAM_set_hostflags(param,
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
@ -150,12 +150,12 @@ lws_ssl_client_bio_create(struct lws *wsi)
#if !defined(USE_WOLFSSL)
#ifndef USE_OLD_CYASSL
/* OpenSSL_client_verify_callback will be called @ SSL_connect() */
SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback);
SSL_set_verify(wsi->tls.ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback);
#endif
#endif
#if !defined(USE_WOLFSSL)
SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_set_mode(wsi->tls.ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
/*
* use server name indication (SNI), if supported,
@ -164,16 +164,16 @@ lws_ssl_client_bio_create(struct lws *wsi)
#ifdef USE_WOLFSSL
#ifdef USE_OLD_CYASSL
#ifdef CYASSL_SNI_HOST_NAME
CyaSSL_UseSNI(wsi->ssl, CYASSL_SNI_HOST_NAME, hostname, strlen(hostname));
CyaSSL_UseSNI(wsi->tls.ssl, CYASSL_SNI_HOST_NAME, hostname, strlen(hostname));
#endif
#else
#ifdef WOLFSSL_SNI_HOST_NAME
wolfSSL_UseSNI(wsi->ssl, WOLFSSL_SNI_HOST_NAME, hostname, strlen(hostname));
wolfSSL_UseSNI(wsi->tls.ssl, WOLFSSL_SNI_HOST_NAME, hostname, strlen(hostname));
#endif
#endif
#else
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
SSL_set_tlsext_host_name(wsi->ssl, hostname);
SSL_set_tlsext_host_name(wsi->tls.ssl, hostname);
#endif
#endif
@ -186,31 +186,31 @@ lws_ssl_client_bio_create(struct lws *wsi)
* Otherwise the connect will simply fail with error code -155
*/
#ifdef USE_OLD_CYASSL
if (wsi->use_ssl == 2)
CyaSSL_set_verify(wsi->ssl, SSL_VERIFY_NONE, NULL);
if (wsi->tls.use_ssl == 2)
CyaSSL_set_verify(wsi->tls.ssl, SSL_VERIFY_NONE, NULL);
#else
if (wsi->use_ssl == 2)
wolfSSL_set_verify(wsi->ssl, SSL_VERIFY_NONE, NULL);
if (wsi->tls.use_ssl == 2)
wolfSSL_set_verify(wsi->tls.ssl, SSL_VERIFY_NONE, NULL);
#endif
#endif /* USE_WOLFSSL */
wsi->client_bio = BIO_new_socket((int)(long long)wsi->desc.sockfd, BIO_NOCLOSE);
SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
wsi->tls.client_bio = BIO_new_socket((int)(long long)wsi->desc.sockfd, BIO_NOCLOSE);
SSL_set_bio(wsi->tls.ssl, wsi->tls.client_bio, wsi->tls.client_bio);
#ifdef USE_WOLFSSL
#ifdef USE_OLD_CYASSL
CyaSSL_set_using_nonblock(wsi->ssl, 1);
CyaSSL_set_using_nonblock(wsi->tls.ssl, 1);
#else
wolfSSL_set_using_nonblock(wsi->ssl, 1);
wolfSSL_set_using_nonblock(wsi->tls.ssl, 1);
#endif
#else
BIO_set_nbio(wsi->client_bio, 1); /* nonblocking */
BIO_set_nbio(wsi->tls.client_bio, 1); /* nonblocking */
#endif
#if defined(LWS_HAVE_SSL_set_alpn_protos) && \
defined(LWS_HAVE_SSL_get0_alpn_selected)
if (wsi->vhost->alpn)
alpn_comma = wsi->vhost->alpn;
if (wsi->vhost->tls.alpn)
alpn_comma = wsi->vhost->tls.alpn;
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
_WSI_TOKEN_CLIENT_ALPN) > 0)
@ -222,10 +222,10 @@ lws_ssl_client_bio_create(struct lws *wsi)
n = lws_alpn_comma_to_openssl(alpn_comma, openssl_alpn,
sizeof(openssl_alpn) - 1);
SSL_set_alpn_protos(wsi->ssl, openssl_alpn, n);
SSL_set_alpn_protos(wsi->tls.ssl, openssl_alpn, n);
#endif
SSL_set_ex_data(wsi->ssl, openssl_websocket_private_data_index, wsi);
SSL_set_ex_data(wsi->tls.ssl, openssl_websocket_private_data_index, wsi);
return 0;
}
@ -238,11 +238,11 @@ lws_tls_client_connect(struct lws *wsi)
char a[32];
unsigned int len;
#endif
int m, n = SSL_connect(wsi->ssl);
int m, n = SSL_connect(wsi->tls.ssl);
if (n == 1) {
#if defined(LWS_HAVE_SSL_set_alpn_protos) && defined(LWS_HAVE_SSL_get0_alpn_selected)
SSL_get0_alpn_selected(wsi->ssl, &prot, &len);
SSL_get0_alpn_selected(wsi->tls.ssl, &prot, &len);
if (len >= sizeof(a))
len = sizeof(a) - 1;
@ -260,10 +260,10 @@ lws_tls_client_connect(struct lws *wsi)
if (m == SSL_ERROR_SYSCALL)
return LWS_SSL_CAPABLE_ERROR;
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl))
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl))
return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl))
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl))
return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
if (!n) /* we don't know what he wants, but he says to retry */
@ -282,7 +282,7 @@ lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len)
int n;
lws_latency_pre(wsi->context, wsi);
n = SSL_get_verify_result(wsi->ssl);
n = SSL_get_verify_result(wsi->tls.ssl);
lws_latency(wsi->context, wsi,
"SSL_get_verify_result LWS_CONNMODE..HANDSHAKE", n, n > 0);
@ -293,14 +293,14 @@ lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len)
if ((n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
(wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED)) {
(wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED)) {
lwsl_info("accepting self-signed certificate\n");
return 0;
}
if ((n == X509_V_ERR_CERT_NOT_YET_VALID ||
n == X509_V_ERR_CERT_HAS_EXPIRED) &&
(wsi->use_ssl & LCCSCF_ALLOW_EXPIRED)) {
(wsi->tls.use_ssl & LCCSCF_ALLOW_EXPIRED)) {
lwsl_info("accepting expired certificate\n");
return 0;
}
@ -353,8 +353,8 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
return 1;
}
/* create context */
vh->ssl_client_ctx = SSL_CTX_new(method);
if (!vh->ssl_client_ctx) {
vh->tls.ssl_client_ctx = SSL_CTX_new(method);
if (!vh->tls.ssl_client_ctx) {
error = ERR_get_error();
lwsl_err("problem creating ssl context %lu: %s\n",
error, ERR_error_string(error,
@ -363,32 +363,32 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
}
#ifdef SSL_OP_NO_COMPRESSION
SSL_CTX_set_options(vh->ssl_client_ctx, SSL_OP_NO_COMPRESSION);
SSL_CTX_set_options(vh->tls.ssl_client_ctx, SSL_OP_NO_COMPRESSION);
#endif
SSL_CTX_set_options(vh->ssl_client_ctx,
SSL_CTX_set_options(vh->tls.ssl_client_ctx,
SSL_OP_CIPHER_SERVER_PREFERENCE);
if (cipher_list)
SSL_CTX_set_cipher_list(vh->ssl_client_ctx, cipher_list);
SSL_CTX_set_cipher_list(vh->tls.ssl_client_ctx, cipher_list);
#ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
/* loads OS default CA certs */
SSL_CTX_set_default_verify_paths(vh->ssl_client_ctx);
SSL_CTX_set_default_verify_paths(vh->tls.ssl_client_ctx);
#endif
/* openssl init for cert verification (for client sockets) */
if (!ca_filepath) {
if (!SSL_CTX_load_verify_locations(
vh->ssl_client_ctx, NULL, LWS_OPENSSL_CLIENT_CERTS))
vh->tls.ssl_client_ctx, NULL, LWS_OPENSSL_CLIENT_CERTS))
lwsl_err("Unable to load SSL Client certs from %s "
"(set by LWS_OPENSSL_CLIENT_CERTS) -- "
"client ssl isn't going to work\n",
LWS_OPENSSL_CLIENT_CERTS);
} else
if (!SSL_CTX_load_verify_locations(
vh->ssl_client_ctx, ca_filepath, NULL)) {
vh->tls.ssl_client_ctx, ca_filepath, NULL)) {
lwsl_err(
"Unable to load SSL Client certs "
"file from %s -- client ssl isn't "
@ -410,7 +410,7 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
return 0;
lwsl_notice("%s: doing cert filepath %s\n", __func__, cert_filepath);
n = SSL_CTX_use_certificate_chain_file(vh->ssl_client_ctx,
n = SSL_CTX_use_certificate_chain_file(vh->tls.ssl_client_ctx,
cert_filepath);
if (n < 1) {
lwsl_err("problem %d getting cert '%s'\n", n,
@ -422,9 +422,9 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
}
if (private_key_filepath) {
lwsl_notice("%s: doing private key filepath\n", __func__);
lws_ssl_bind_passphrase(vh->ssl_client_ctx, info);
lws_ssl_bind_passphrase(vh->tls.ssl_client_ctx, info);
/* set the private key from KeyFile */
if (SSL_CTX_use_PrivateKey_file(vh->ssl_client_ctx,
if (SSL_CTX_use_PrivateKey_file(vh->tls.ssl_client_ctx,
private_key_filepath, SSL_FILETYPE_PEM) != 1) {
lwsl_err("use_PrivateKey_file '%s'\n",
private_key_filepath);
@ -435,7 +435,7 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
private_key_filepath);
/* verify private key */
if (!SSL_CTX_check_private_key(vh->ssl_client_ctx)) {
if (!SSL_CTX_check_private_key(vh->tls.ssl_client_ctx)) {
lwsl_err("Private SSL key doesn't match cert\n");
return 1;
}

View file

@ -72,11 +72,11 @@ lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)
LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
SSL_CTX_set_session_id_context(vh->ssl_ctx, (uint8_t *)vh->context,
SSL_CTX_set_session_id_context(vh->tls.ssl_ctx, (uint8_t *)vh->context,
sizeof(void *));
/* absolutely require the client cert */
SSL_CTX_set_verify(vh->ssl_ctx, verify_options, OpenSSL_verify_callback);
SSL_CTX_set_verify(vh->tls.ssl_ctx, verify_options, OpenSSL_verify_callback);
return 0;
}
@ -100,7 +100,7 @@ lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
vh = context->vhost_list;
while (vh) {
if (!vh->being_destroyed &&
vh->ssl_ctx == SSL_get_SSL_CTX(ssl))
vh->tls.ssl_ctx == SSL_get_SSL_CTX(ssl))
break;
vh = vh->vhost_next;
}
@ -128,7 +128,7 @@ lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
lwsl_info("SNI: Found: %s:%d\n", servername, vh->listen_port);
/* select the ssl ctx from the selected vhost for this conn */
SSL_set_SSL_CTX(ssl, vhost->ssl_ctx);
SSL_set_SSL_CTX(ssl, vhost->tls.ssl_ctx);
return SSL_TLSEXT_ERR_OK;
}
@ -182,11 +182,11 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
* memory-buffer private key image is PEM.
*/
#ifndef USE_WOLFSSL
if (SSL_CTX_use_certificate_ASN1(vhost->ssl_ctx,
if (SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx,
(int)len_mem_cert,
(uint8_t *)mem_cert) != 1) {
#else
if (wolfSSL_CTX_use_certificate_buffer(vhost->ssl_ctx,
if (wolfSSL_CTX_use_certificate_buffer(vhost->tls.ssl_ctx,
(uint8_t *)mem_cert,
(int)len_mem_cert,
WOLFSSL_FILETYPE_ASN1) != 1) {
@ -205,10 +205,10 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
return 1;
}
#ifndef USE_WOLFSSL
if (SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, vhost->ssl_ctx,
if (SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, vhost->tls.ssl_ctx,
p, (long)(long long)flen) != 1) {
#else
if (wolfSSL_CTX_use_PrivateKey_buffer(vhost->ssl_ctx,
if (wolfSSL_CTX_use_PrivateKey_buffer(vhost->tls.ssl_ctx,
p, flen, WOLFSSL_FILETYPE_ASN1) != 1) {
#endif
lwsl_notice("unable to use memory privkey\n");
@ -220,7 +220,7 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
}
/* set the local certificate from CertFile */
m = SSL_CTX_use_certificate_chain_file(vhost->ssl_ctx, cert);
m = SSL_CTX_use_certificate_chain_file(vhost->tls.ssl_ctx, cert);
if (m != 1) {
error = ERR_get_error();
lwsl_err("problem getting cert '%s' %lu: %s\n",
@ -232,7 +232,7 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
if (n != LWS_TLS_EXTANT_ALTERNATIVE && private_key) {
/* set the private key from KeyFile */
if (SSL_CTX_use_PrivateKey_file(vhost->ssl_ctx, private_key,
if (SSL_CTX_use_PrivateKey_file(vhost->tls.ssl_ctx, private_key,
SSL_FILETYPE_PEM) != 1) {
error = ERR_get_error();
lwsl_err("ssl problem getting key '%s' %lu: %s\n",
@ -244,7 +244,7 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
} else {
if (vhost->protocols[0].callback(wsi,
LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
vhost->ssl_ctx, NULL, 0)) {
vhost->tls.ssl_ctx, NULL, 0)) {
lwsl_err("ssl private key not set\n");
return 1;
@ -253,15 +253,15 @@ lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
check_key:
/* verify private key */
if (!SSL_CTX_check_private_key(vhost->ssl_ctx)) {
if (!SSL_CTX_check_private_key(vhost->tls.ssl_ctx)) {
lwsl_err("Private SSL key doesn't match cert\n");
return 1;
}
#if defined(LWS_HAVE_OPENSSL_ECDH_H)
if (vhost->ecdh_curve[0])
ecdh_curve = vhost->ecdh_curve;
if (vhost->tls.ecdh_curve[0])
ecdh_curve = vhost->tls.ecdh_curve;
ecdh_nid = OBJ_sn2nid(ecdh_curve);
if (NID_undef == ecdh_nid) {
@ -274,10 +274,10 @@ check_key:
lwsl_err("SSL: Unable to create curve '%s'", ecdh_curve);
return 1;
}
SSL_CTX_set_tmp_ecdh(vhost->ssl_ctx, ecdh);
SSL_CTX_set_tmp_ecdh(vhost->tls.ssl_ctx, ecdh);
EC_KEY_free(ecdh);
SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
lwsl_notice(" SSL ECDH curve '%s'\n", ecdh_curve);
@ -287,9 +287,9 @@ check_key:
/* Get X509 certificate from ssl context */
#if !defined(LWS_WITH_BORINGSSL)
#if !defined(LWS_HAVE_SSL_EXTRA_CHAIN_CERTS)
x = sk_X509_value(vhost->ssl_ctx->extra_certs, 0);
x = sk_X509_value(vhost->tls.ssl_ctx->extra_certs, 0);
#else
SSL_CTX_get_extra_chain_certs_only(vhost->ssl_ctx, &extra_certs);
SSL_CTX_get_extra_chain_certs_only(vhost->tls.ssl_ctx, &extra_certs);
if (extra_certs)
x = sk_X509_value(extra_certs, 0);
else
@ -323,7 +323,7 @@ check_key:
lwsl_err("%s: ECDH key is NULL \n", __func__);
return 1;
}
SSL_CTX_set_tmp_ecdh(vhost->ssl_ctx, EC_key);
SSL_CTX_set_tmp_ecdh(vhost->tls.ssl_ctx, EC_key);
EC_KEY_free(EC_key);
#else
@ -332,7 +332,7 @@ check_key:
#if defined(LWS_HAVE_OPENSSL_ECDH_H) && !defined(LWS_WITH_BORINGSSL)
post_ecdh:
#endif
vhost->skipped_certs = 0;
vhost->tls.skipped_certs = 0;
return 0;
}
@ -352,8 +352,8 @@ lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info,
(char *)vhost->context->pt[0].serv_buf));
return 1;
}
vhost->ssl_ctx = SSL_CTX_new(method); /* create context */
if (!vhost->ssl_ctx) {
vhost->tls.ssl_ctx = SSL_CTX_new(method); /* create context */
if (!vhost->tls.ssl_ctx) {
error = ERR_get_error();
lwsl_err("problem creating ssl context %lu: %s\n",
error, ERR_error_string(error,
@ -361,46 +361,46 @@ lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info,
return 1;
}
SSL_CTX_set_ex_data(vhost->ssl_ctx, openssl_SSL_CTX_private_data_index,
SSL_CTX_set_ex_data(vhost->tls.ssl_ctx, openssl_SSL_CTX_private_data_index,
(char *)vhost->context);
/* Disable SSLv2 and SSLv3 */
SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
#ifdef SSL_OP_NO_COMPRESSION
SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_NO_COMPRESSION);
SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_NO_COMPRESSION);
#endif
SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_SINGLE_DH_USE);
SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_SINGLE_DH_USE);
SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
if (info->ssl_cipher_list)
SSL_CTX_set_cipher_list(vhost->ssl_ctx, info->ssl_cipher_list);
SSL_CTX_set_cipher_list(vhost->tls.ssl_ctx, info->ssl_cipher_list);
#if !defined(OPENSSL_NO_TLSEXT)
SSL_CTX_set_tlsext_servername_callback(vhost->ssl_ctx,
SSL_CTX_set_tlsext_servername_callback(vhost->tls.ssl_ctx,
lws_ssl_server_name_cb);
SSL_CTX_set_tlsext_servername_arg(vhost->ssl_ctx, vhost->context);
SSL_CTX_set_tlsext_servername_arg(vhost->tls.ssl_ctx, vhost->context);
#endif
if (info->ssl_ca_filepath &&
!SSL_CTX_load_verify_locations(vhost->ssl_ctx,
!SSL_CTX_load_verify_locations(vhost->tls.ssl_ctx,
info->ssl_ca_filepath, NULL)) {
lwsl_err("%s: SSL_CTX_load_verify_locations unhappy\n",
__func__);
}
if (info->ssl_options_set)
SSL_CTX_set_options(vhost->ssl_ctx, info->ssl_options_set);
SSL_CTX_set_options(vhost->tls.ssl_ctx, info->ssl_options_set);
/* SSL_clear_options introduced in 0.9.8m */
#if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL)
if (info->ssl_options_clear)
SSL_CTX_clear_options(vhost->ssl_ctx, info->ssl_options_clear);
SSL_CTX_clear_options(vhost->tls.ssl_ctx, info->ssl_options_clear);
#endif
lwsl_info(" SSL options 0x%lX\n", (unsigned long)SSL_CTX_get_options(vhost->ssl_ctx));
if (!vhost->use_ssl || !info->ssl_cert_filepath)
lwsl_info(" SSL options 0x%lX\n", (unsigned long)SSL_CTX_get_options(vhost->tls.ssl_ctx));
if (!vhost->tls.use_ssl || !info->ssl_cert_filepath)
return 0;
lws_ssl_bind_passphrase(vhost->ssl_ctx, info);
lws_ssl_bind_passphrase(vhost->tls.ssl_ctx, info);
return lws_tls_server_certs_load(vhost, wsi, info->ssl_cert_filepath,
info->ssl_private_key_filepath,
@ -415,8 +415,8 @@ lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd)
#endif
errno = 0;
wsi->ssl = SSL_new(wsi->vhost->ssl_ctx);
if (wsi->ssl == NULL) {
wsi->tls.ssl = SSL_new(wsi->vhost->tls.ssl_ctx);
if (wsi->tls.ssl == NULL) {
lwsl_err("SSL_new failed: %d (errno %d)\n",
lws_ssl_get_error(wsi, 0), errno);
@ -424,24 +424,24 @@ lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd)
return 1;
}
SSL_set_ex_data(wsi->ssl, openssl_websocket_private_data_index, wsi);
SSL_set_fd(wsi->ssl, (int)(long long)accept_fd);
SSL_set_ex_data(wsi->tls.ssl, openssl_websocket_private_data_index, wsi);
SSL_set_fd(wsi->tls.ssl, (int)(long long)accept_fd);
#ifdef USE_WOLFSSL
#ifdef USE_OLD_CYASSL
CyaSSL_set_using_nonblock(wsi->ssl, 1);
CyaSSL_set_using_nonblock(wsi->tls.ssl, 1);
#else
wolfSSL_set_using_nonblock(wsi->ssl, 1);
wolfSSL_set_using_nonblock(wsi->tls.ssl, 1);
#endif
#else
SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
bio = SSL_get_rbio(wsi->ssl);
SSL_set_mode(wsi->tls.ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
bio = SSL_get_rbio(wsi->tls.ssl);
if (bio)
BIO_set_nbio(bio, 1); /* nonblocking */
else
lwsl_notice("NULL rbio\n");
bio = SSL_get_wbio(wsi->ssl);
bio = SSL_get_wbio(wsi->tls.ssl);
if (bio)
BIO_set_nbio(bio, 1); /* nonblocking */
else
@ -449,8 +449,8 @@ lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd)
#endif
#if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
if (wsi->vhost->ssl_info_event_mask)
SSL_set_info_callback(wsi->ssl, lws_ssl_info_callback);
if (wsi->vhost->tls.ssl_info_event_mask)
SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback);
#endif
return 0;
@ -459,8 +459,8 @@ lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd)
int
lws_tls_server_abort_connection(struct lws *wsi)
{
SSL_shutdown(wsi->ssl);
SSL_free(wsi->ssl);
SSL_shutdown(wsi->tls.ssl);
SSL_free(wsi->tls.ssl);
return 0;
}
@ -469,7 +469,7 @@ enum lws_ssl_capable_status
lws_tls_server_accept(struct lws *wsi)
{
union lws_tls_cert_info_results ir;
int m, n = SSL_accept(wsi->ssl);
int m, n = SSL_accept(wsi->tls.ssl);
if (n == 1) {
n = lws_tls_peer_cert_info(wsi, LWS_TLS_CERT_INFO_COMMON_NAME, &ir,
@ -487,7 +487,7 @@ lws_tls_server_accept(struct lws *wsi)
if (m == SSL_ERROR_SYSCALL || m == SSL_ERROR_SSL)
return LWS_SSL_CAPABLE_ERROR;
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl)) {
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
lwsl_info("%s: WANT_READ change_pollfd failed\n",
__func__);
@ -497,7 +497,7 @@ lws_tls_server_accept(struct lws *wsi)
lwsl_info("SSL_ERROR_WANT_READ\n");
return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
}
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) {
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
lwsl_debug("%s: WANT_WRITE\n", __func__);
if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
@ -561,33 +561,33 @@ lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
if (!gens)
return 1;
vhost->ss = lws_zalloc(sizeof(*vhost->ss), "sni cert");
if (!vhost->ss) {
vhost->tls.ss = lws_zalloc(sizeof(*vhost->tls.ss), "sni cert");
if (!vhost->tls.ss) {
GENERAL_NAMES_free(gens);
return 1;
}
vhost->ss->x509 = X509_new();
if (!vhost->ss->x509)
vhost->tls.ss->x509 = X509_new();
if (!vhost->tls.ss->x509)
goto bail;
ASN1_INTEGER_set(X509_get_serialNumber(vhost->ss->x509), 1);
X509_gmtime_adj(X509_get_notBefore(vhost->ss->x509), 0);
X509_gmtime_adj(X509_get_notAfter(vhost->ss->x509), 3600);
ASN1_INTEGER_set(X509_get_serialNumber(vhost->tls.ss->x509), 1);
X509_gmtime_adj(X509_get_notBefore(vhost->tls.ss->x509), 0);
X509_gmtime_adj(X509_get_notAfter(vhost->tls.ss->x509), 3600);
vhost->ss->pkey = EVP_PKEY_new();
if (!vhost->ss->pkey)
vhost->tls.ss->pkey = EVP_PKEY_new();
if (!vhost->tls.ss->pkey)
goto bail0;
if (lws_tls_openssl_rsa_new_key(&vhost->ss->rsa, 4096))
if (lws_tls_openssl_rsa_new_key(&vhost->tls.ss->rsa, 4096))
goto bail1;
if (!EVP_PKEY_assign_RSA(vhost->ss->pkey, vhost->ss->rsa))
if (!EVP_PKEY_assign_RSA(vhost->tls.ss->pkey, vhost->tls.ss->rsa))
goto bail2;
X509_set_pubkey(vhost->ss->x509, vhost->ss->pkey);
X509_set_pubkey(vhost->tls.ss->x509, vhost->tls.ss->pkey);
name = X509_get_subject_name(vhost->ss->x509);
name = X509_get_subject_name(vhost->tls.ss->x509);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
(unsigned char *)"GB", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
@ -598,7 +598,7 @@ lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
lwsl_notice("failed to add CN\n");
goto bail2;
}
X509_set_issuer_name(vhost->ss->x509, name);
X509_set_issuer_name(vhost->tls.ss->x509, name);
/* add the SAN payloads */
@ -612,7 +612,7 @@ lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
GENERAL_NAME_set0_value(gen, GEN_DNS, ia5);
sk_GENERAL_NAME_push(gens, gen);
if (X509_add1_ext_i2d(vhost->ss->x509, NID_subject_alt_name,
if (X509_add1_ext_i2d(vhost->tls.ss->x509, NID_subject_alt_name,
gens, 0, X509V3_ADD_APPEND) != 1)
goto bail2;
@ -630,7 +630,7 @@ lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
GENERAL_NAME_set0_value(gen, GEN_DNS, ia5);
sk_GENERAL_NAME_push(gens, gen);
if (X509_add1_ext_i2d(vhost->ss->x509, NID_subject_alt_name,
if (X509_add1_ext_i2d(vhost->tls.ss->x509, NID_subject_alt_name,
gens, 0, X509V3_ADD_APPEND) != 1)
goto bail2;
@ -638,33 +638,33 @@ lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
}
/* sign it with our private key */
if (!X509_sign(vhost->ss->x509, vhost->ss->pkey, EVP_sha256()))
if (!X509_sign(vhost->tls.ss->x509, vhost->tls.ss->pkey, EVP_sha256()))
goto bail2;
#if 0
{/* useful to take a sample of a working cert for mbedtls to crib */
FILE *fp = fopen("/tmp/acme-temp-cert", "w+");
i2d_X509_fp(fp, vhost->ss->x509);
i2d_X509_fp(fp, vhost->tls.ss->x509);
fclose(fp);
}
#endif
/* tell the vhost to use our crafted certificate */
SSL_CTX_use_certificate(vhost->ssl_ctx, vhost->ss->x509);
SSL_CTX_use_certificate(vhost->tls.ssl_ctx, vhost->tls.ss->x509);
/* and to use our generated private key */
SSL_CTX_use_PrivateKey(vhost->ssl_ctx, vhost->ss->pkey);
SSL_CTX_use_PrivateKey(vhost->tls.ssl_ctx, vhost->tls.ss->pkey);
return 0;
bail2:
RSA_free(vhost->ss->rsa);
RSA_free(vhost->tls.ss->rsa);
bail1:
EVP_PKEY_free(vhost->ss->pkey);
EVP_PKEY_free(vhost->tls.ss->pkey);
bail0:
X509_free(vhost->ss->x509);
X509_free(vhost->tls.ss->x509);
bail:
lws_free(vhost->ss);
lws_free(vhost->tls.ss);
GENERAL_NAMES_free(gens);
return 1;
@ -673,12 +673,12 @@ bail:
void
lws_tls_acme_sni_cert_destroy(struct lws_vhost *vhost)
{
if (!vhost->ss)
if (!vhost->tls.ss)
return;
EVP_PKEY_free(vhost->ss->pkey);
X509_free(vhost->ss->x509);
lws_free_set_NULL(vhost->ss);
EVP_PKEY_free(vhost->tls.ss->pkey);
X509_free(vhost->tls.ss->x509);
lws_free_set_NULL(vhost->tls.ss);
}
static int

View file

@ -29,11 +29,11 @@ int lws_ssl_get_error(struct lws *wsi, int n)
{
int m;
if (!wsi->ssl)
if (!wsi->tls.ssl)
return 99;
m = SSL_get_error(wsi->ssl, n);
lwsl_debug("%s: %p %d -> %d (errno %d)\n", __func__, wsi->ssl, n, m, errno);
m = SSL_get_error(wsi->tls.ssl, n);
lwsl_debug("%s: %p %d -> %d (errno %d)\n", __func__, wsi->tls.ssl, n, m, errno);
return m;
}
@ -162,10 +162,10 @@ lws_ssl_destroy(struct lws_vhost *vhost)
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
return;
if (vhost->ssl_ctx)
SSL_CTX_free(vhost->ssl_ctx);
if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
SSL_CTX_free(vhost->ssl_client_ctx);
if (vhost->tls.ssl_ctx)
SSL_CTX_free(vhost->tls.ssl_ctx);
if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx)
SSL_CTX_free(vhost->tls.ssl_client_ctx);
// after 1.1.0 no need
#if (OPENSSL_VERSION_NUMBER < 0x10100000)
@ -198,13 +198,13 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
int n = 0, m;
if (!wsi->ssl)
if (!wsi->tls.ssl)
return lws_ssl_capable_read_no_ssl(wsi, buf, len);
lws_stats_atomic_bump(context, pt, LWSSTATS_C_API_READ, 1);
errno = 0;
n = SSL_read(wsi->ssl, buf, len);
n = SSL_read(wsi->tls.ssl, buf, len);
#if defined(LWS_WITH_ESP32)
if (!n && errno == ENOTCONN) {
lwsl_debug("%p: SSL_read ENOTCONN\n", wsi);
@ -236,12 +236,12 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
m == SSL_ERROR_SYSCALL)
return LWS_SSL_CAPABLE_ERROR;
if (SSL_want_read(wsi->ssl)) {
if (SSL_want_read(wsi->tls.ssl)) {
lwsl_debug("%s: WANT_READ\n", __func__);
lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi);
return LWS_SSL_CAPABLE_MORE_SERVICE;
}
if (SSL_want_write(wsi->ssl)) {
if (SSL_want_write(wsi->tls.ssl)) {
lwsl_debug("%s: WANT_WRITE\n", __func__);
lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi);
return LWS_SSL_CAPABLE_MORE_SERVICE;
@ -267,26 +267,26 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
*/
if (n != len)
goto bail;
if (!wsi->ssl)
if (!wsi->tls.ssl)
goto bail;
if (!SSL_pending(wsi->ssl))
if (!SSL_pending(wsi->tls.ssl))
goto bail;
if (wsi->pending_read_list_next)
if (wsi->tls.pending_read_list_next)
return n;
if (wsi->pending_read_list_prev)
if (wsi->tls.pending_read_list_prev)
return n;
if (pt->pending_read_list == wsi)
if (pt->tls.pending_read_list == wsi)
return n;
/* add us to the linked list of guys with pending ssl */
if (pt->pending_read_list)
pt->pending_read_list->pending_read_list_prev = wsi;
if (pt->tls.pending_read_list)
pt->tls.pending_read_list->tls.pending_read_list_prev = wsi;
wsi->pending_read_list_next = pt->pending_read_list;
wsi->pending_read_list_prev = NULL;
pt->pending_read_list = wsi;
wsi->tls.pending_read_list_next = pt->tls.pending_read_list;
wsi->tls.pending_read_list_prev = NULL;
pt->tls.pending_read_list = wsi;
return n;
bail:
@ -298,10 +298,10 @@ bail:
LWS_VISIBLE int
lws_ssl_pending(struct lws *wsi)
{
if (!wsi->ssl)
if (!wsi->tls.ssl)
return 0;
return SSL_pending(wsi->ssl);
return SSL_pending(wsi->tls.ssl);
}
LWS_VISIBLE int
@ -309,22 +309,22 @@ lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
{
int n, m;
if (!wsi->ssl)
if (!wsi->tls.ssl)
return lws_ssl_capable_write_no_ssl(wsi, buf, len);
n = SSL_write(wsi->ssl, buf, len);
n = SSL_write(wsi->tls.ssl, buf, len);
if (n > 0)
return n;
m = lws_ssl_get_error(wsi, n);
if (m != SSL_ERROR_SYSCALL) {
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl)) {
if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
lwsl_notice("%s: want read\n", __func__);
return LWS_SSL_CAPABLE_MORE_SERVICE;
}
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) {
if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
lws_set_blocking_send(wsi);
lwsl_notice("%s: want write\n", __func__);
@ -363,7 +363,7 @@ lws_ssl_info_callback(const SSL *ssl, int where, int ret)
if (!wsi)
return;
if (!(where & wsi->vhost->ssl_info_event_mask))
if (!(where & wsi->vhost->tls.ssl_info_event_mask))
return;
si.where = where;
@ -381,23 +381,23 @@ lws_ssl_close(struct lws *wsi)
{
lws_sockfd_type n;
if (!wsi->ssl)
if (!wsi->tls.ssl)
return 0; /* not handled */
#if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
/* kill ssl callbacks, becausse we will remove the fd from the
* table linking it to the wsi
*/
if (wsi->vhost->ssl_info_event_mask)
SSL_set_info_callback(wsi->ssl, NULL);
if (wsi->vhost->tls.ssl_info_event_mask)
SSL_set_info_callback(wsi->tls.ssl, NULL);
#endif
n = SSL_get_fd(wsi->ssl);
n = SSL_get_fd(wsi->tls.ssl);
if (!wsi->socket_is_permanently_unusable)
SSL_shutdown(wsi->ssl);
SSL_shutdown(wsi->tls.ssl);
compatible_close(n);
SSL_free(wsi->ssl);
wsi->ssl = NULL;
SSL_free(wsi->tls.ssl);
wsi->tls.ssl = NULL;
if (wsi->context->simultaneous_ssl_restriction &&
wsi->context->simultaneous_ssl-- ==
@ -419,11 +419,11 @@ lws_ssl_close(struct lws *wsi)
void
lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
{
if (vhost->ssl_ctx)
SSL_CTX_free(vhost->ssl_ctx);
if (vhost->tls.ssl_ctx)
SSL_CTX_free(vhost->tls.ssl_ctx);
if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
SSL_CTX_free(vhost->ssl_client_ctx);
if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx)
SSL_CTX_free(vhost->tls.ssl_client_ctx);
#if defined(LWS_WITH_ACME)
lws_tls_acme_sni_cert_destroy(vhost);
#endif
@ -459,10 +459,10 @@ lws_ssl_context_destroy(struct lws_context *context)
lws_tls_ctx *
lws_tls_ctx_from_wsi(struct lws *wsi)
{
if (!wsi->ssl)
if (!wsi->tls.ssl)
return NULL;
return SSL_get_SSL_CTX(wsi->ssl);
return SSL_get_SSL_CTX(wsi->tls.ssl);
}
enum lws_ssl_capable_status
@ -470,7 +470,7 @@ __lws_tls_shutdown(struct lws *wsi)
{
int n;
n = SSL_shutdown(wsi->ssl);
n = SSL_shutdown(wsi->tls.ssl);
lwsl_debug("SSL_shutdown=%d for fd %d\n", n, wsi->desc.sockfd);
switch (n) {
case 1: /* successful completion */
@ -482,14 +482,14 @@ __lws_tls_shutdown(struct lws *wsi)
return LWS_SSL_CAPABLE_MORE_SERVICE;
default: /* fatal error, or WANT */
n = SSL_get_error(wsi->ssl, n);
n = SSL_get_error(wsi->tls.ssl, n);
if (n != SSL_ERROR_SYSCALL && n != SSL_ERROR_SSL) {
if (SSL_want_read(wsi->ssl)) {
if (SSL_want_read(wsi->tls.ssl)) {
lwsl_debug("(wants read)\n");
__lws_change_pollfd(wsi, 0, LWS_POLLIN);
return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
}
if (SSL_want_write(wsi->ssl)) {
if (SSL_want_write(wsi->tls.ssl)) {
lwsl_debug("(wants write)\n");
__lws_change_pollfd(wsi, 0, LWS_POLLOUT);
return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
@ -643,7 +643,7 @@ lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
union lws_tls_cert_info_results *buf, size_t len)
{
#if defined(LWS_HAVE_SSL_CTX_get0_certificate)
X509 *x509 = SSL_CTX_get0_certificate(vhost->ssl_ctx);
X509 *x509 = SSL_CTX_get0_certificate(vhost->tls.ssl_ctx);
return lws_tls_openssl_cert_info(x509, type, buf, len);
#else
@ -662,7 +662,7 @@ lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
wsi = lws_get_network_wsi(wsi);
x509 = SSL_get_peer_certificate(wsi->ssl);
x509 = SSL_get_peer_certificate(wsi->tls.ssl);
if (!x509) {
lwsl_debug("no peer cert\n");
@ -672,7 +672,7 @@ lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
switch (type) {
case LWS_TLS_CERT_INFO_VERIFIED:
buf->verified = SSL_get_verify_result(wsi->ssl) == X509_V_OK;
buf->verified = SSL_get_verify_result(wsi->tls.ssl) == X509_V_OK;
break;
default:
rc = lws_tls_openssl_cert_info(x509, type, buf, len);
@ -682,3 +682,14 @@ lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
return rc;
}
static int
tops_fake_POLLIN_for_buffered_openssl(struct lws_context_per_thread *pt)
{
return lws_tls_fake_POLLIN_for_buffered(pt);
}
const struct lws_tls_ops tls_ops_openssl = {
/* fake_POLLIN_for_buffered */ tops_fake_POLLIN_for_buffered_openssl,
};

View file

@ -21,6 +21,8 @@
* This is included from private-libwebsockets.h if LWS_WITH_TLS
*/
#if defined(LWS_WITH_TLS)
#if defined(USE_WOLFSSL)
#if defined(USE_OLD_CYASSL)
#if defined(_WIN32)
@ -79,18 +81,77 @@
#endif /* not ESP32 */
#endif /* not USE_WOLFSSL */
typedef SSL lws_tls_conn;
typedef SSL_CTX lws_tls_ctx;
typedef BIO lws_tls_bio;
typedef X509 lws_tls_x509;
#define LWS_SSL_ENABLED(context) (context->use_ssl)
#endif /* LWS_WITH_TLS */
enum lws_tls_extant {
LWS_TLS_EXTANT_NO,
LWS_TLS_EXTANT_YES,
LWS_TLS_EXTANT_ALTERNATIVE
};
struct lws_context_per_thread;
struct lws_tls_ops {
int (*fake_POLLIN_for_buffered)(struct lws_context_per_thread *pt);
};
#if defined(LWS_WITH_TLS)
typedef SSL lws_tls_conn;
typedef SSL_CTX lws_tls_ctx;
typedef BIO lws_tls_bio;
typedef X509 lws_tls_x509;
#define LWS_SSL_ENABLED(context) (context->tls.use_ssl)
extern const struct lws_tls_ops tls_ops_openssl, tls_ops_mbedtls;
struct lws_context_tls {
char alpn_discovered[32];
const char *alpn_default;
};
struct lws_pt_tls {
struct lws *pending_read_list; /* linked list */
};
struct lws_tls_ss_pieces;
struct alpn_ctx {
uint8_t data[23];
uint8_t len;
};
struct lws_vhost_tls {
lws_tls_ctx *ssl_ctx;
lws_tls_ctx *ssl_client_ctx;
const char *alpn;
struct lws_tls_ss_pieces *ss; /* for acme tls certs */
char *alloc_cert_path;
char *key_path;
#if defined(LWS_WITH_MBEDTLS)
lws_tls_x509 *x509_client_CA;
#endif
char ecdh_curve[16];
struct alpn_ctx alpn_ctx;
int use_ssl;
int allow_non_ssl_on_ssl_port;
int ssl_info_event_mask;
unsigned int user_supplied_ssl_ctx:1;
unsigned int skipped_certs:1;
};
struct lws_lws_tls {
lws_tls_conn *ssl;
lws_tls_bio *client_bio;
struct lws *pending_read_list_prev, *pending_read_list_next;
unsigned int use_ssl;
unsigned int redirect_to_https:1;
};
LWS_EXTERN void
lws_context_init_alpn(struct lws_vhost *vhost);
LWS_EXTERN enum lws_tls_extant
@ -125,7 +186,7 @@ lws_ssl_client_connect2(struct lws *wsi, char *errbuf, int len);
LWS_EXTERN void
lws_ssl_elaborate_error(void);
LWS_EXTERN int
lws_ssl_anybody_has_buffered_read_tsi(struct lws_context *context, int tsi);
lws_tls_fake_POLLIN_for_buffered(struct lws_context_per_thread *pt);
LWS_EXTERN int
lws_gate_accepts(struct lws_context *context, int on);
LWS_EXTERN void
@ -211,3 +272,8 @@ lws_context_init_client_ssl(const struct lws_context_creation_info *info,
LWS_EXTERN void
lws_ssl_info_callback(const lws_tls_conn *ssl, int where, int ret);
int
lws_tls_fake_POLLIN_for_buffered(struct lws_context_per_thread *pt);
#endif

View file

@ -115,14 +115,14 @@ int lws_context_init_client_ssl(const struct lws_context_creation_info *info,
if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
return 0;
if (vhost->ssl_client_ctx)
if (vhost->tls.ssl_client_ctx)
return 0;
if (info->provided_client_ssl_ctx) {
/* use the provided OpenSSL context if given one */
vhost->ssl_client_ctx = info->provided_client_ssl_ctx;
vhost->tls.ssl_client_ctx = info->provided_client_ssl_ctx;
/* nothing for lib to delete */
vhost->user_supplied_ssl_ctx = 1;
vhost->tls.user_supplied_ssl_ctx = 1;
return 0;
}
@ -144,7 +144,7 @@ int lws_context_init_client_ssl(const struct lws_context_creation_info *info,
vhost->protocols[0].callback(&wsi,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
vhost->ssl_client_ctx, NULL, 0);
vhost->tls.ssl_client_ctx, NULL, 0);
return 0;
}

View file

@ -45,18 +45,18 @@ lws_context_init_alpn(struct lws_vhost *vhost)
{
#if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && \
OPENSSL_VERSION_NUMBER >= 0x10002000L)
const char *alpn_comma = vhost->context->alpn_default;
const char *alpn_comma = vhost->context->tls.alpn_default;
if (vhost->alpn)
alpn_comma = vhost->alpn;
if (vhost->tls.alpn)
alpn_comma = vhost->tls.alpn;
lwsl_info(" Server '%s' advertising ALPN: %s\n",
vhost->name, alpn_comma);
vhost->alpn_ctx.len = lws_alpn_comma_to_openssl(alpn_comma,
vhost->alpn_ctx.data,
sizeof(vhost->alpn_ctx.data) - 1);
vhost->tls.alpn_ctx.len = lws_alpn_comma_to_openssl(alpn_comma,
vhost->tls.alpn_ctx.data,
sizeof(vhost->tls.alpn_ctx.data) - 1);
SSL_CTX_set_alpn_select_cb(vhost->ssl_ctx, alpn_cb, &vhost->alpn_ctx);
SSL_CTX_set_alpn_select_cb(vhost->tls.ssl_ctx, alpn_cb, &vhost->tls.alpn_ctx);
#else
lwsl_err(
" HTTP2 / ALPN configured but not supported by OpenSSL 0x%lx\n",
@ -73,7 +73,7 @@ lws_tls_server_conn_alpn(struct lws *wsi)
char cstr[10];
unsigned len;
SSL_get0_alpn_selected(wsi->ssl, &name, &len);
SSL_get0_alpn_selected(wsi->tls.ssl, &name, &len);
if (!len) {
lwsl_info("no ALPN upgrade\n");
return 0;
@ -86,7 +86,7 @@ lws_tls_server_conn_alpn(struct lws *wsi)
cstr[len] = '\0';
lwsl_info("negotiated '%s' using ALPN\n", cstr);
wsi->use_ssl |= LCCSCF_USE_SSL;
wsi->tls.use_ssl |= LCCSCF_USE_SSL;
return lws_role_call_alpn_negotiated(wsi, (const char *)cstr);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
@ -103,7 +103,7 @@ lws_context_init_server_ssl(const struct lws_context_creation_info *info,
if (!lws_check_opt(info->options,
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) {
vhost->use_ssl = 0;
vhost->tls.use_ssl = 0;
return 0;
}
@ -121,14 +121,14 @@ lws_context_init_server_ssl(const struct lws_context_creation_info *info,
if (info->port != CONTEXT_PORT_NO_LISTEN) {
vhost->use_ssl = lws_check_opt(vhost->options,
vhost->tls.use_ssl = lws_check_opt(vhost->options,
LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX);
if (vhost->use_ssl && info->ssl_cipher_list)
if (vhost->tls.use_ssl && info->ssl_cipher_list)
lwsl_notice(" SSL ciphers: '%s'\n",
info->ssl_cipher_list);
if (vhost->use_ssl)
if (vhost->tls.use_ssl)
lwsl_notice(" Using SSL mode\n");
else
lwsl_notice(" Using non-SSL mode\n");
@ -149,13 +149,13 @@ lws_context_init_server_ssl(const struct lws_context_creation_info *info,
if (lws_check_opt(info->options,
LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT))
/* Normally SSL listener rejects non-ssl, optionally allow */
vhost->allow_non_ssl_on_ssl_port = 1;
vhost->tls.allow_non_ssl_on_ssl_port = 1;
/*
* give user code a chance to load certs into the server
* allowing it to verify incoming client certs
*/
if (vhost->use_ssl) {
if (vhost->tls.use_ssl) {
if (lws_tls_server_vhost_backend_init(info, vhost, &wsi))
return -1;
@ -163,11 +163,11 @@ lws_context_init_server_ssl(const struct lws_context_creation_info *info,
if (vhost->protocols[0].callback(&wsi,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
vhost->ssl_ctx, vhost, 0))
vhost->tls.ssl_ctx, vhost, 0))
return -1;
}
if (vhost->use_ssl)
if (vhost->tls.use_ssl)
lws_context_init_alpn(vhost);
return 0;
@ -190,7 +190,7 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
switch (lwsi_state(wsi)) {
case LRS_SSL_INIT:
if (wsi->ssl)
if (wsi->tls.ssl)
lwsl_err("%s: leaking ssl\n", __func__);
if (accept_fd == LWS_SOCK_INVALID)
assert(0);
@ -246,7 +246,7 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
lws_latency_pre(context, wsi);
if (wsi->vhost->allow_non_ssl_on_ssl_port) {
if (wsi->vhost->tls.allow_non_ssl_on_ssl_port) {
n = recv(wsi->desc.sockfd, (char *)pt->serv_buf,
context->pt_serv_buf_size, MSG_PEEK);
@ -268,7 +268,7 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
* connection and try to handle as a HTTP
* connection upgrade directly.
*/
wsi->use_ssl = 0;
wsi->tls.use_ssl = 0;
lws_tls_server_abort_connection(wsi);
/*
@ -276,10 +276,10 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
* when ssl is enabled and normally
* mandatory
*/
wsi->ssl = NULL;
wsi->tls.ssl = NULL;
if (lws_check_opt(context->options,
LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS))
wsi->redirect_to_https = 1;
wsi->tls.redirect_to_https = 1;
lwsl_debug("accepted as non-ssl\n");
goto accepted;
}
@ -351,8 +351,8 @@ accepted:
/* adapt our vhost to match the SNI SSL_CTX that was chosen */
vh = context->vhost_list;
while (vh) {
if (!vh->being_destroyed && wsi->ssl &&
vh->ssl_ctx == lws_tls_ctx_from_wsi(wsi)) {
if (!vh->being_destroyed && wsi->tls.ssl &&
vh->tls.ssl_ctx == lws_tls_ctx_from_wsi(wsi)) {
lwsl_info("setting wsi to vh %s\n", vh->name);
wsi->vhost = vh;
break;

View file

@ -21,24 +21,29 @@
#include "private-libwebsockets.h"
int
lws_ssl_anybody_has_buffered_read_tsi(struct lws_context *context, int tsi)
{
struct lws_context_per_thread *pt = &context->pt[tsi];
struct lws *wsi, *wsi_next;
/*
* fakes POLLIN on all tls guys with buffered rx
*
* returns nonzero if any tls guys had POLLIN faked
*/
wsi = pt->pending_read_list;
int
lws_tls_fake_POLLIN_for_buffered(struct lws_context_per_thread *pt)
{
struct lws *wsi, *wsi_next;
int ret = 0;
wsi = pt->tls.pending_read_list;
while (wsi) {
wsi_next = wsi->pending_read_list_next;
wsi_next = wsi->tls.pending_read_list_next;
pt->fds[wsi->position_in_fds_table].revents |=
pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN;
if (pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN)
return 1;
ret |= pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN;
wsi = wsi_next;
}
return 0;
return !!ret;
}
void
@ -47,26 +52,26 @@ __lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi)
struct lws_context *context = wsi->context;
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
if (!wsi->pending_read_list_prev &&
!wsi->pending_read_list_next &&
pt->pending_read_list != wsi)
if (!wsi->tls.pending_read_list_prev &&
!wsi->tls.pending_read_list_next &&
pt->tls.pending_read_list != wsi)
/* we are not on the list */
return;
/* point previous guy's next to our next */
if (!wsi->pending_read_list_prev)
pt->pending_read_list = wsi->pending_read_list_next;
if (!wsi->tls.pending_read_list_prev)
pt->tls.pending_read_list = wsi->tls.pending_read_list_next;
else
wsi->pending_read_list_prev->pending_read_list_next =
wsi->pending_read_list_next;
wsi->tls.pending_read_list_prev->tls.pending_read_list_next =
wsi->tls.pending_read_list_next;
/* point next guy's previous to our previous */
if (wsi->pending_read_list_next)
wsi->pending_read_list_next->pending_read_list_prev =
wsi->pending_read_list_prev;
if (wsi->tls.pending_read_list_next)
wsi->tls.pending_read_list_next->tls.pending_read_list_prev =
wsi->tls.pending_read_list_prev;
wsi->pending_read_list_prev = NULL;
wsi->pending_read_list_next = NULL;
wsi->tls.pending_read_list_prev = NULL;
wsi->tls.pending_read_list_next = NULL;
}
void
@ -238,7 +243,7 @@ lws_tls_check_cert_lifetime(struct lws_vhost *v)
struct lws_acme_cert_aging_args caa;
int n;
if (v->ssl_ctx && !v->skipped_certs) {
if (v->tls.ssl_ctx && !v->tls.skipped_certs) {
if (now < 1464083026) /* May 2016 */
/* our clock is wrong and we can't judge the certs */
@ -410,7 +415,7 @@ lws_tls_generic_cert_checks(struct lws_vhost *vhost, const char *cert,
if ((n == LWS_TLS_EXTANT_NO || m == LWS_TLS_EXTANT_NO) &&
(vhost->options & LWS_SERVER_OPTION_IGNORE_MISSING_CERT)) {
lwsl_notice("Ignoring missing %s or %s\n", cert, private_key);
vhost->skipped_certs = 1;
vhost->tls.skipped_certs = 1;
return LWS_TLS_EXTANT_NO;
}
@ -439,14 +444,14 @@ lws_tls_cert_updated(struct lws_context *context, const char *certpath,
lws_start_foreach_ll(struct lws_vhost *, v, context->vhost_list) {
wsi.vhost = v;
if (v->alloc_cert_path && v->key_path &&
!strcmp(v->alloc_cert_path, certpath) &&
!strcmp(v->key_path, keypath)) {
if (v->tls.alloc_cert_path && v->tls.key_path &&
!strcmp(v->tls.alloc_cert_path, certpath) &&
!strcmp(v->tls.key_path, keypath)) {
lws_tls_server_certs_load(v, &wsi, certpath, keypath,
mem_cert, len_mem_cert,
mem_privkey, len_mem_privkey);
if (v->skipped_certs)
if (v->tls.skipped_certs)
lwsl_notice("%s: vhost %s: cert unset\n",
__func__, v->name);
}
@ -462,13 +467,13 @@ lws_gate_accepts(struct lws_context *context, int on)
struct lws_vhost *v = context->vhost_list;
lwsl_notice("%s: on = %d\n", __func__, on);
context->ssl_gate_accepts = !on;
#if defined(LWS_WITH_STATS)
context->updated = 1;
#endif
while (v) {
if (v->use_ssl && v->lserv_wsi &&
if (v->tls.use_ssl && v->lserv_wsi &&
lws_change_pollfd(v->lserv_wsi, (LWS_POLLIN) * !on,
(LWS_POLLIN) * on))
lwsl_notice("Unable to set accept POLLIN %d\n", on);

View file

@ -17,6 +17,7 @@
#endif
#include <string.h>
#include <stdlib.h>
/* one of these created for each message */

View file

@ -240,7 +240,8 @@ int main(int argc, const char **argv)
* OpenSSL uses the system trust store. mbedTLS has to be told which
* CA to trust explicitly.
*/
info.client_ssl_ca_filepath = "./libwebsockets.org.cer";
if (!lws_cmdline_option(argc, argv, "-l"))
info.client_ssl_ca_filepath = "./libwebsockets.org.cer";
#endif
context = lws_create_context(&info);

View file

@ -42,10 +42,12 @@ spawn() {
fi
fi
QQ=`pwd`
cd $SCRIPT_DIR
cd $2
$3 $4 $5 > $LOGPATH/$MYTEST/serverside.log 2> $LOGPATH/$MYTEST/serverside.log &
SPID=$!
cd $QQ
sleep 0.5s
# echo "launched prerequisite $SPID"
}
@ -80,6 +82,7 @@ dotest() {
R=`cat $2/$MYTEST/$T.result`
cat $2/$MYTEST/$T.log | tail -n 3 > $2/$MYTEST/$T.time
if [ $R -ne 0 ] ; then
pwd
echo
cat $2/$MYTEST/$T.log
echo

View file

@ -15,6 +15,10 @@ echo
LOGGING_PATH=/tmp/logs
# for mebedtls, we need the CA certs in ./build where we run from
cp ../minimal-examples/http-client/minimal-http-client-multi/warmcat.com.cer .
cp ../minimal-examples/http-client/minimal-http-client-post/libwebsockets.org.cer .
MINEX=`dirname $0`
MINEX=`realpath $MINEX`

View file

@ -28,6 +28,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define TEST_SERVER_KEY_PATH "/etc/lws-test-sshd-server-key"

View file

@ -554,15 +554,17 @@ for i in \
/a/w/../a \
/path/to/dir/../other/dir \
; do
R=`rm -f /tmp/lwscap ; echo -n -e "GET $i HTTP/1.0\r\n\r\n" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null > /tmp/lwscap; head -n1 /tmp/lwscap| cut -d' ' -f2`
LEN=`stat $LOG -c %s`
rm -f /tmp/lwscap1
echo -n -e "GET $i HTTP/1.0\r\n\r\n" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null > /tmp/lwscap1
R=`cat /tmp/lwscap1| head -n 1 | cut -d' ' -f 2`
#cat $LOG
#echo ==== $R
if [ "$R" != "403" ]; then
U=`cat $LOG | grep Method: | tail -n 1 | cut -d"'" -f4 | sed "s|\\'||g"`
U=`dd if=$LOG bs=1 skip=$LEN 2>/dev/null| grep "Method:" | tr -s ' ' | cut -d"'" -f4`
#dd if=$LOG bs=1 skip=$LEN 2>/dev/null
echo "- \"$i\" -> $R \"$U\"" >>/tmp/results
else
echo "- \"$i\" -> $R" >>/tmp/results

View file

@ -1,9 +1,11 @@
#/bin/bash
if [ "$COVERITY_SCAN_BRANCH" != 1 -a "$TRAVIS_OS_NAME" = "osx" ]; then
mkdir build && cd build &&
cmake -DOPENSSL_ROOT_DIR="/usr/local/opt/openssl" $CMAKE_ARGS .. &&
cmake --build .
if [ "$LWS_METHOD" != "mbedtls" ] ; then
mkdir build && cd build &&
cmake -DOPENSSL_ROOT_DIR="/usr/local/opt/openssl" $CMAKE_ARGS .. &&
cmake --build .
fi
else
if [ "$COVERITY_SCAN_BRANCH" != 1 -a "$TRAVIS_OS_NAME" = "linux" ]; then
mkdir build && cd build &&
@ -20,12 +22,22 @@ else
else
if [ "$LWS_METHOD" = "smp" ] ; then
cmake -DLWS_OPENSSL_LIBRARIES="/usr/local/lib/libssl.so;/usr/local/lib/libcrypto.so" \
-DLWS_OPENSSL_INCLUDE_DIRS="/usr/local/include/openssl" $CMAKE_ARGS .. &&
-DLWS_OPENSSL_INCLUDE_DIRS="/usr/local/include/openssl" $CMAKE_ARGS .. &&
cmake --build . &&
../scripts/h2load-smp.sh
else
cmake $CMAKE_ARGS .. &&
cmake --build .
if [ "$LWS_METHOD" = "mbedtls" ] ; then
cmake $CMAKE_ARGS .. &&
cmake --build . &&
sudo make install &&
../minimal-examples/selftests.sh &&
../scripts/h2spec.sh &&
../scripts/h2load.sh &&
../scripts/attack.sh
else
cmake $CMAKE_ARGS .. &&
cmake --build .
fi
fi
fi
fi

View file

@ -8,7 +8,7 @@ then
if [ "$LWS_METHOD" == "lwsws" ];
then
sudo apt-get install -y -qq realpath libjemalloc1 libev4
sudo apt-get install -y -qq realpath libjemalloc1 libev4 libuv-dev
sudo apt-get remove python-six
sudo pip install six>=1.9
sudo pip install Twisted==16.0.0
@ -21,6 +21,16 @@ then
sudo update-ca-certificates
fi
if [ "$LWS_METHOD" == "mbedtls" ];
then
sudo apt-get install -y -qq realpath libjemalloc1 libev4 libuv-dev
wget https://libwebsockets.org/openssl-1.1.0-trusty.tar.bz2 -O/tmp/openssl.tar.bz2
cd /
sudo tar xf /tmp/openssl.tar.bz2
sudo ldconfig
sudo update-ca-certificates
fi
if [ "$LWS_METHOD" == "smp" ];
then
sudo apt-get install -y -qq realpath libjemalloc1 libev4