#define TLS_CONNECT_TASK_STACK_SIZE 524288 #define TLS_CLIENT_MESSAGE_BUFFER_SIZE 0xFFFF class TlsSocket : TcpSocket { U64 ctx; U8 client_message[TLS_CLIENT_MESSAGE_BUFFER_SIZE]; }; U0 @tls_send_pending(TlsSocket* s) { U32 out_buffer_len = 0; U8* out_buffer = @tls_get_write_buffer(s->ctx, &out_buffer_len); if (out_buffer && out_buffer_len) { @tcp_socket_send(s, out_buffer, out_buffer_len); @tls_buffer_clear(s->ctx); } } U0 @tls_socket_send(TlsSocket* s, U64 buf, U64 size) { @tls_write(s->ctx, buf, size); @tls_send_pending(s); } U64 @tls_socket_receive(TlsSocket* s, U8* buf, I64 size) { I64 len = @tcp_socket_receive(s, s->client_message, TLS_CLIENT_MESSAGE_BUFFER_SIZE); if (len) { @tls_consume_stream(s->ctx, s->client_message, len, NULL); @tls_send_pending(s); } return @tls_read(s->ctx, buf, size); } U0 @tls12_connect(TlsSocket* s) { I64 len; @tls_client_connect(s->ctx); @tls_send_pending(s); while (!@tls_established(s->ctx)) { len = @tcp_socket_receive(s, &s->client_message, TLS_CLIENT_MESSAGE_BUFFER_SIZE); if (len) { @tls_consume_stream(s->ctx, &s->client_message, len, NULL); @tls_send_pending(s); } Sleep(1); } } TlsSocket* @tls_socket_create(U8* server_name, U64 port = 443) { U64 addr = @dns_query(server_name); TlsSocket* s = CAlloc(sizeof(TlsSocket), erythros_mem_task->code_heap); s->remote_addr = addr; s->remote_port = port; U64 a; s->close = MAlloc(16, erythros_mem_task->code_heap); MemCpy(s->close, @tcp_close_wrapper_function, 16); a = s->close; a += 0x05; MemSetU32(a, s, 1); a = s->close; a += 0x09; @patch_call_rel32(a, &@tcp_socket_close); s->receive = MAlloc(25, erythros_mem_task->code_heap); MemCpy(s->receive, @tcp_receive_wrapper_function, 32); a = s->receive; a += 0x11; MemSetU32(a, s, 1); a = s->receive; a += 0x15; @patch_call_rel32(a, &@tls_socket_receive); s->send = MAlloc(32, erythros_mem_task->code_heap); MemCpy(s->send, @tcp_send_wrapper_function, 32); a = s->send; a += 0x11; MemSetU32(a, s, 1); a = s->send; a += 0x15; @patch_call_rel32(a, &@tls_socket_send); U64* request_ptr = TCP_SOCKET_REQUEST_PTR; while (*request_ptr) Sleep(1); LXchgU32(request_ptr, s); while (s->state != TCP_SOCKET_STATE_ESTABLISHED) Sleep(1); s->ctx = @tls_create_context(0, TLS_V12); @tls_sni_set(s->ctx, StrNew(server_name, erythros_mem_task->code_heap)); Spawn(&@tls12_connect, s, , , , TLS_CONNECT_TASK_STACK_SIZE); return s; }