Skip to content

Commit 42e27c2

Browse files
committed
stage/bug fix ssl/tls handling
- add/update dependency, stay compatible with openssl 1.1.0, build zlib if not installed - add ssl/tls test, buggy
1 parent 2e8434c commit 42e27c2

7 files changed

Lines changed: 202 additions & 135 deletions

File tree

CMakeLists.txt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ target_link_libraries(asio PUBLIC uv_a)
5252
target_include_directories(asio AFTER PUBLIC $<BUILD_INTERFACE:${RAII_INCLUDE_DIR} $<INSTALL_INTERFACE:${RAII_INCLUDE_DIR})
5353
target_link_libraries(asio PUBLIC raii)
5454

55-
find_package(OpenSSL 1.1.0...<3.0.0)
55+
find_package(OpenSSL 1.1.0...3.0.2)
5656
if(OPENSSL_FOUND)
5757
target_include_directories(asio PUBLIC $<BUILD_INTERFACE:${OPENSSL_INCLUDE_DIR} $<INSTALL_INTERFACE:${OPENSSL_INCLUDE_DIR})
5858
if(WIN32)
@@ -97,6 +97,27 @@ else()
9797
add_definitions("/wd4244 /wd4267 /wd4033 /wd4715 /wd4996")
9898
endif()
9999

100+
find_package(ZLIB CONFIG)
101+
if(ZLIB_FOUND)
102+
target_include_directories(asio PUBLIC $<BUILD_INTERFACE:${ZLIB_INCLUDE_DIR} $<INSTALL_INTERFACE:${INSTALL_INC_DIR})
103+
message(STATUS "Cmake FindZLIB: using ZLIB includes at: ${ZLIB_INCLUDE_DIR}")
104+
message(STATUS "Cmake FindZLIB: using ZLIB libraries: ${ZLIB_LIBRARIES}")
105+
else()
106+
FetchContent_Declare(ZLIB
107+
URL https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz
108+
URL_MD5 9855b6d802d7fe5b7bd5b196a2271655
109+
)
110+
FetchContent_MakeAvailable(ZLIB)
111+
option(ZLIB_BUILD_MINIZIP "Enable building libminizip contrib" OFF)
112+
option(ZLIB_BUILD_EXAMPLES "Enable Zlib Examples as tests" OFF)
113+
option(ZLIB_INSTALL "Enable installation of zlib" ON)
114+
set(ZLIB_BUILD_EXAMPLES OFF CACHE BOOL "Build tests" FORCE)
115+
set(ZLIB_BUILD_MINIZIP OFF CACHE BOOL "Build libminizip" FORCE)
116+
set(ZLIB_INSTALL ON CACHE BOOL "Install zlib" FORCE)
117+
target_include_directories(asio PUBLIC $<BUILD_INTERFACE:${INSTALL_INC_DIR} $<INSTALL_INTERFACE:${INSTALL_INC_DIR})
118+
endif()
119+
target_link_libraries(asio PUBLIC ${ZLIB_LIBRARIES})
120+
100121
# enable the address sanitizer to catch bugs
101122
option(ENABLE_ASAN "Enable AddressSanitizer for Debug builds" ON)
102123

include/asio.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -530,19 +530,20 @@ C_API u32 delay(u32 ms);
530530
#define _BIO_MODE_W(flags) "w"
531531
#endif
532532
/* OpenSSL Certificate */
533-
typedef struct certificate_object asio_cert_t;
533+
typedef struct certificate_object ASIO_cert_t;
534534

535535
/* OpenSSL AsymmetricKey */
536-
typedef struct pkey_object asio_pkey_t;
536+
typedef struct pkey_object ASIO_pkey_t;
537537

538538
/* OpenSSL Certificate Signing Request */
539-
typedef struct x509_request_object asio_req_t;
539+
typedef struct x509_request_object ASIO_req_t;
540540

541-
C_API void asio_ssl_error(void);
541+
C_API void ASIO_ssl_error(void);
542+
C_API void ASIO_ssl_init(void);
542543

543-
C_API asio_pkey_t *pkey_create(u32 num_pairs, ...);
544-
C_API asio_req_t *csr_create(EVP_PKEY *pkey, u32 num_pairs, ...);
545-
C_API asio_cert_t *x509_create(EVP_PKEY *pkey, u32 num_pairs, ...);
544+
C_API ASIO_pkey_t *pkey_create(u32 num_pairs, ...);
545+
C_API ASIO_req_t *csr_create(EVP_PKEY *pkey, u32 num_pairs, ...);
546+
C_API ASIO_cert_t *x509_create(EVP_PKEY *pkey, u32 num_pairs, ...);
546547

547548
C_API bool pkey_x509_export(EVP_PKEY *pkey, string_t path_noext);
548549
C_API bool csr_x509_export(X509_REQ *req, string_t path_noext);

src/asio.c

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct uv_args_s {
2121
routine_t *context;
2222

2323
evt_ctx_t ctx;
24+
uv_tls_t *tls;
2425
string buffer;
2526
uv_buf_t bufs;
2627
uv_fs_t fs_req;
@@ -189,7 +190,7 @@ static void tls_close_free(void_t handle) {
189190
if (!h || UV_UNKNOWN_HANDLE == h->type)
190191
return;
191192

192-
uv_tls_close((uv_tls_t *)h, (uv_tls_close_cb)RAII_FREE);
193+
uv_tls_close((uv_tls_t *)handle, (uv_tls_close_cb)RAII_FREE);
193194
}
194195

195196
static void asio_closer(uv_args_t *uv) {
@@ -396,6 +397,8 @@ static void on_listen_handshake(uv_tls_t *ut, int status) {
396397

397398
if (status < 0)
398399
coro_err_set(co, status);
400+
else
401+
uv_handle_set_data(handler(ut->tcp_hdl), (void_t)uv);
399402

400403
coro_await_finish(co, (!status ? streamer(ut->tcp_hdl) : nullptr), status, (status < 0));
401404
}
@@ -415,17 +418,19 @@ static void connection_cb(uv_stream_t *server, int status) {
415418
bool is_ready = false, halt = true;
416419

417420
if (status == 0) {
418-
if (uv->bind_type == RAII_SCHEME_TLS) {
421+
if (uv->bind_type == UV_TLS) {
419422
handle = RAII_CALLOC(1, sizeof(uv_tcp_t));
420423
r = uv_tcp_init(uvLoop, (uv_tcp_t *)handle);
421424
if (!r && !(r = uv_accept(server, (uv_stream_t *)handle))) {
422425
uv_tls_t *client = RAII_MALLOC(sizeof(uv_tls_t)); //freed on uv_close callback
423-
if (!(r = uv_tls_init(&uv->ctx, handle, client))) {
426+
if ((r = uv_tls_init(&uv->ctx, handle, client)) < 0) {
427+
RAII_FREE(client);
428+
} else {
424429
halt = false;
425-
r = uv_tls_accept(client, on_listen_handshake);
430+
uv->tls = client;
431+
client->type = UV_TLS;
426432
client->uv_args = (void_t)uv;
427-
} else {
428-
RAII_FREE(client);
433+
uv_tls_accept(client, on_listen_handshake);
429434
}
430435
}
431436
} else if (uv->bind_type == RAII_SCHEME_TCP) {
@@ -436,7 +441,7 @@ static void connection_cb(uv_stream_t *server, int status) {
436441
r = uv_pipe_init(uvLoop, (uv_pipe_t *)handle, 0);
437442
}
438443

439-
if (!r && (uv->bind_type != RAII_SCHEME_TLS)) {
444+
if (!r && (uv->bind_type != UV_TLS)) {
440445
if (!(r = uv_accept(server, streamer(handle)))) {
441446
is_ready = true;
442447
uv_handle_set_data(handler(handle), (void_t)uv);
@@ -453,7 +458,7 @@ static void connection_cb(uv_stream_t *server, int status) {
453458
}
454459

455460
coro_await_upgrade(co, (is_ready ? streamer(handle) : nullptr),
456-
r, r, halt, (uv->bind_type != RAII_SCHEME_TLS));
461+
r, r, halt, (uv->bind_type != UV_TLS));
457462
}
458463

459464
static void getnameinfo_cb(uv_getnameinfo_t *req, int status, string_t hostname, string_t service) {
@@ -813,9 +818,10 @@ static void_t uv_init(params_t uv_args) {
813818
switch (uv->req_type) {
814819
case UV_WRITE:
815820
req = (uv_req_t *)&uv->write_req;
816-
if (uv->bind_type == RAII_SCHEME_TLS) {
817-
((uv_tls_t *)stream)->uv_args = uv;
818-
result = uv_tls_write((uv_tls_t *)stream, &uv->bufs, tls_write_cb);
821+
if (uv->bind_type == UV_TLS) {
822+
uv->tls->data = (uv_tcp_t *)stream;
823+
uv->tls->uv_args = (void_t)uv;
824+
result = uv_tls_write(uv->tls, &uv->bufs, tls_write_cb);
819825
} else {
820826
result = uv_write((uv_write_t *)req, streamer(stream), &uv->bufs, 1, write_cb);
821827
}
@@ -828,7 +834,7 @@ static void_t uv_init(params_t uv_args) {
828834
uv_pipe_connect((uv_connect_t *)req, (uv_pipe_t *)stream, (string_t)args[1].char_ptr, connect_cb);
829835
result = 0;
830836
break;
831-
case RAII_SCHEME_TLS:
837+
case UV_TLS:
832838
req->data = &uv->ctx;
833839
result = uv_tcp_connect((uv_connect_t *)req, (uv_tcp_t *)stream, (sockaddr_t *)args[1].object, on_connect);
834840
break;
@@ -876,13 +882,13 @@ static void_t uv_init(params_t uv_args) {
876882
break;
877883
}
878884

879-
if (uv->bind_type == RAII_SCHEME_TLS)
885+
if (uv->bind_type == UV_TLS)
880886
uv->ctx.uv_args = (void_t)uv;
881887
else if (!result)
882888
uv_req_set_data(req, (void_t)uv);
883889

884890
} else {
885-
if (uv->bind_type != RAII_SCHEME_TLS)
891+
if (uv->bind_type != UV_TLS)
886892
uv_handle_set_data(stream, (void_t)uv);
887893

888894
switch (uv->handle_type) {
@@ -925,7 +931,7 @@ static void_t uv_init(params_t uv_args) {
925931
fprintf(stdout, "Listening to %s:%d for%s connections, %s.\033[0K\n",
926932
(uv->bind_type == RAII_SCHEME_PIPE ? name : uv->dns->ip),
927933
args[4].integer,
928-
(uv->bind_type == RAII_SCHEME_TLS ? " secure" : ""),
934+
(uv->bind_type == UV_TLS ? " secure" : ""),
929935
http_std_date(0)
930936
);
931937

@@ -934,9 +940,10 @@ static void_t uv_init(params_t uv_args) {
934940
}
935941
break;
936942
case UV_STREAM:
937-
if (uv->bind_type == RAII_SCHEME_TLS) {
938-
((uv_tls_t *)stream)->uv_args = (void_t)uv;
939-
result = uv_tls_read(((uv_tls_t *)stream), tls_read_cb);
943+
if (uv->bind_type == UV_TLS) {
944+
uv->tls->data = (void_t)stream;
945+
uv->tls->uv_args = (void_t)uv;
946+
result = uv_tls_read(uv->tls, tls_read_cb);
940947
} else {
941948
result = uv_read_start((uv_stream_t *)stream, alloc_cb, read_cb);
942949
}
@@ -1437,13 +1444,20 @@ nameinfo_t *get_nameinfo(string_t addr, int port, int flags) {
14371444
static void_t stream_client(params_t args) {
14381445
uv_stream_t *client = (uv_stream_t *)args[0].object;
14391446
stream_cb handlerFunc = (stream_cb)args[1].func;
1440-
raii_type type = ((uv_args_t *)uv_handle_get_data(handler(client)))->bind_type;
1441-
1442-
uv_handle_set_data(handler(client), nullptr);
1443-
if (type == RAII_SCHEME_TLS)
1444-
defer(tls_close_free, client);
1445-
else
1447+
uv_args_t *uv = (uv_args_t *)uv_handle_get_data(handler(client));
1448+
1449+
if (uv->bind_type == RAII_SCHEME_TLS) {
1450+
uv_args_t *tls_args = uv_arguments(1, true);
1451+
tls_args->tls = uv->tls;
1452+
tls_args->bind_type = uv->bind_type;
1453+
$append(tls_args->args, client);
1454+
uv_handle_set_data(handler(client), (void_t)tls_args);
1455+
tls_args->tls->data = (uv_tcp_t *)client;
1456+
defer(tls_close_free, uv->tls);
1457+
} else {
1458+
uv_handle_set_data(handler(client), nullptr);
14461459
defer(uv_close_free, client);
1460+
}
14471461

14481462
handlerFunc(client);
14491463

@@ -1477,13 +1491,15 @@ RAII_INLINE string stream_read_wait(uv_stream_t *handle) {
14771491
if (is_empty(handle))
14781492
return nullptr;
14791493

1480-
uv_args_t *uv_args = (uv_args_t *)uv_handle_get_data(handler(handle));
1481-
if (is_defined(uv_args) || is_tls(handle)) {
1482-
uv_args->args[0].object = handle;
1483-
} else {
1494+
uv_args_t *uv_args = nullptr;
1495+
void_t check = uv_handle_get_data(handler(handle));
1496+
if (is_empty(check)) {
14841497
uv_args = uv_arguments(1, true);
14851498
$append(uv_args->args, handle);
14861499
uv_handle_set_data(handler(handle), (void_t)uv_args);
1500+
} else {
1501+
uv_args = (uv_args_t *)check;
1502+
uv_args->args[0].object = handle;
14871503
}
14881504

14891505
return uv_start(uv_args, UV_STREAM, 1, false).char_ptr;
@@ -1558,7 +1574,6 @@ static string stream_get(uv_stream_t *handle) {
15581574
if (is_empty(handle))
15591575
return nullptr;
15601576

1561-
bool has_args = false;
15621577
generator_t gen = nullptr;
15631578
uv_args_t *uv_args = (uv_args_t *)uv_handle_get_data(handler(handle));
15641579
if (is_defined(uv_args) && uv_args->is_generator) {
@@ -1637,8 +1652,8 @@ uv_stream_t *stream_connect_ex(uv_handle_type scheme, string_t address, int port
16371652
uv_args->bind_type = RAII_SCHEME_PIPE;
16381653
handle = pipe_create(false);
16391654
break;
1640-
case RAII_SCHEME_TLS:
1641-
uv_args->bind_type = RAII_SCHEME_TLS;
1655+
case UV_TLS:
1656+
uv_args->bind_type = UV_TLS;
16421657
if (is_str_eq(name, "localhost"))
16431658
name = (string)asio_hostname();
16441659

@@ -1726,7 +1741,7 @@ uv_stream_t *stream_bind_ex(uv_handle_type scheme, string_t address, int port, i
17261741
if (!r)
17271742
defer((func_t)fs_remove_pipe, uv_args);
17281743
break;
1729-
case RAII_SCHEME_TLS:
1744+
case UV_TLS:
17301745
if (is_str_eq(name, "localhost"))
17311746
name = (string)asio_hostname();
17321747

@@ -1760,7 +1775,7 @@ uv_stream_t *stream_bind_ex(uv_handle_type scheme, string_t address, int port, i
17601775
$append_signed(uv_args->args, port);
17611776

17621777
uv_args->bind_type = scheme;
1763-
if (scheme == RAII_SCHEME_TLS)
1778+
if (scheme == UV_TLS)
17641779
uv_args->ctx.data = (void_t)uv_args;
17651780
else
17661781
uv_handle_set_data(handler(handle), (void_t)uv_args);
@@ -2287,7 +2302,7 @@ tty_err_t *tty_err(void) {
22872302
}
22882303

22892304
static uv_tcp_t *tls_tcp_create(void_t extra) {
2290-
uv_tcp_t *tcp = (uv_tcp_t *)calloc_full(coro_scope(), 1, sizeof(uv_tcp_t), tls_close_free);
2305+
uv_tcp_t *tcp = (uv_tcp_t *)calloc_full(coro_scope(), 1, sizeof(uv_tcp_t), uv_close_free);
22912306
tcp->data = extra;
22922307
int r = uv_tcp_init(asio_loop(), tcp);
22932308
if (r) {
@@ -2550,13 +2565,6 @@ RAII_INLINE bool is_process(void_t self) {
25502565
return is_type(self, (raii_type)ASIO_SPAWN);
25512566
}
25522567

2553-
RAII_INLINE bool is_tls(uv_stream_t *self) {
2554-
if (!self)
2555-
return false;
2556-
2557-
return is_type(uv_handle_get_data(handler(self)), RAII_SCHEME_TLS);
2558-
}
2559-
25602568
RAII_INLINE bool is_pipepair(void_t self) {
25612569
return is_type(self, (raii_type)ASIO_PIPE);
25622570
}
@@ -2609,6 +2617,14 @@ RAII_INLINE bool is_tcp(void_t self) {
26092617
return is_defined(check) && ((uv_args_t *)check)->bind_type == RAII_SCHEME_TCP;
26102618
}
26112619

2620+
RAII_INLINE bool is_tls(uv_stream_t *self) {
2621+
if (!self)
2622+
return false;
2623+
2624+
void_t check = uv_handle_get_data(handler(self));
2625+
return is_defined(check) && ((uv_args_t *)check)->bind_type == UV_TLS;
2626+
}
2627+
26122628
RAII_INLINE bool is_udp(void_t self) {
26132629
if (!self || is_udp_packet(self))
26142630
return false;

0 commit comments

Comments
 (0)