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:
parent
da0be64f68
commit
bce8cca042
35 changed files with 614 additions and 483 deletions
|
@ -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"
|
||||
|
|
12
README.md
12
README.md
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -33,6 +33,9 @@ extern "C" {
|
|||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lws_config.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
||||
};
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* one of these created for each message */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define TEST_SERVER_KEY_PATH "/etc/lws-test-sshd-server-key"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue