Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- errno_t g_tls_t::init_ctx(G_TLS_MODE_E mode)
- {
- #if !defined(WIN32) && !defined(_WIN64) && !USE_TLS_OPENSSL_MEM
- signal(SIGPIPE, SIG_IGN);
- #endif
- // load & register all cryptos, etc.
- // not needed since OpenSSL 1.1.0
- //-OpenSSL_add_all_algorithms();
- // load all error messages
- tls_load_error_strings();
- if (mode & G_TLS_SERVER)
- {
- wprintf(L"%" _HS_ L"\n", TLS_VERSION);
- server_valid = false;
- // create new server context from method
- ctx_server = SSL_CTX_new(tls_server_method());
- if (ctx_server == NULL)
- {
- //- tls_err_print_errors_fp(stderr);
- wprintf(L"cannot create server SSL context\n\n");
- return FAIL;
- }
- }
- if (mode & G_TLS_CLIENT)
- {
- wprintf(L"%" _HS_ L"\n", TLS_VERSION);
- client_valid = false;
- // create new client context from method
- ctx_client = SSL_CTX_new(tls_client_method());
- if (ctx_client == NULL)
- {
- //- tls_err_print_errors_fp(stderr);
- wprintf(L"cannot create client SSL context\n\n");
- return FAIL;
- }
- client_valid = true;
- }
- return OK;
- }
- errno_t g_tls_t::load_cer(G_TLS_MODE_E mode)
- {
- if (mode == G_TLS_SERVER)
- {
- server_valid = false;
- }
- TLS_CTX_T ctx = (mode == G_TLS_CLIENT) ? ctx_client : ctx_server;
- if (!ctx)
- {
- return FAIL;
- }
- #if defined(WIN32) || defined(_WIN64)
- char * p_cer = c_cer;
- char * p_key = c_key;
- // openssl does not support wchar_t
- // convert wchar_t to char
- if (OK != key_to_c_key())
- {
- return FAIL;
- }
- #else
- char * p_cer = cer;
- char * p_key = key;
- #endif
- // set the local certificate from cer
- if (SSL_CTX_use_certificate_file(ctx, p_cer, SSL_FILETYPE_PEM) <= 0)
- {
- if (show_errors)
- {
- wprintf(L"invalid or missing certificate file\n%" _HS_ L"\n\n", p_cer);
- }
- return FAIL;
- }
- // set the private key from key (may be the same as cer)
- if (SSL_CTX_use_PrivateKey_file(ctx, p_key, SSL_FILETYPE_PEM) <= 0)
- {
- if (show_errors)
- {
- wprintf(L"invalid or missing key file\n%" _HS_ L"\n\n", p_key);
- }
- return FAIL;
- }
- // verify private key
- if (!SSL_CTX_check_private_key(ctx))
- {
- if (show_errors)
- {
- fprintf(stderr, "Private key does not match the public certificate\n");
- }
- return FAIL;
- }
- if (mode == G_TLS_SERVER)
- {
- server_valid = true;
- }
- return OK;
- }
- errno_t g_tls_t::new_session(SOCKET so, G_TLS_MODE_E mode)
- {
- this->so = so;
- bool valid = (mode == G_TLS_CLIENT) ? client_valid : server_valid;
- if (!valid || (so == INVALID_SOCKET))
- {
- return FAIL;
- }
- tls = SSL_new((mode == G_TLS_CLIENT) ? ctx_client : ctx_server);
- if (!tls)
- {
- return FAIL;
- }
- #if USE_TLS_OPENSSL_MEM
- b_recv = BIO_new(BIO_s_mem());
- b_send = BIO_new(BIO_s_mem());
- if (!(b_recv && b_send))
- {
- if (b_recv)
- {
- BIO_free(b_recv);
- b_recv = NULL;
- }
- if (b_send)
- {
- BIO_free(b_send);
- b_send = NULL;
- }
- tls_free(tls);
- return FAIL;
- }
- SSL_set_bio(tls, b_recv, b_send);
- #else
- tls_set_fd(tls, (int)so);
- #endif
- InterlockedExchange(&ref, 1);
- error_code = OK;
- return OK;
- }
- errno_t g_tls_t::accept()
- {
- TLS_SESSION_T tls_tmp = tls;
- if (!tls)
- {
- return FAIL;
- }
- if (InterlockedExchangeAdd(&ref, 1) <= 0)
- {
- InterlockedDecrement(&ref);
- error_code = FAIL;
- return FAIL;
- }
- #if USE_TLS_OPENSSL_MEM
- int b = FAIL;
- if (!p_recv || !p_recv_size)
- {
- error_code = FAIL;
- wprintf(L"p_recv or p_recv_size not set\n");
- }
- else
- {
- RECV_MORE:
- if (!SSL_is_init_finished(tls))
- {
- ssize_t size = ::recv(so, p_recv, (int)p_recv_size, 0);
- if (size <= 0)
- {
- error_code = WSAGetLastError();
- //- wprintf(L"tls.accept::recv %i\n", error_code);
- }
- else
- {
- size = tls ? BIO_write(b_recv, p_recv, (int)size) : FAIL;
- if (size <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- //- wprintf(L"tls.accept::BIO_write %i\n", error_code);
- }
- else
- {
- error_code = OK;
- b = SSL_accept(tls);
- if (b <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, b) : FAIL;
- //- wprintf(L"tls.accept::SSL_accept %i\n", error_code);
- }
- if (
- (error_code == OK) ||
- (error_code == SSL_ERROR_WANT_READ)
- )
- {
- size = tls ? BIO_read(b_send, p_recv, (int)p_recv_size) : FAIL;
- if (size <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- //- wprintf(L"tls.accept::BIO_read %i\n", error_code);
- }
- else
- {
- size = send_raw(p_recv, size);
- if (size <= 0)
- {
- error_code = WSAGetLastError();
- //- wprintf(L"tls.accept::send %i\n", error_code);
- }
- }
- if (error_code == SSL_ERROR_WANT_READ)
- {
- // SSL_accept or BIO_read require more data from client
- goto RECV_MORE;
- }
- }
- }
- }
- }
- }
- #else
- int b = SSL_accept(tls_tmp);
- if (b <= 0)
- {
- error_code = SSL_get_error(tls_tmp, b);
- }
- #endif
- if (!InterlockedDecrement(&ref))
- {
- tls_shutdown(tls_tmp);
- tls_free(tls_tmp);
- }
- return (1 == b) ? OK : FAIL;
- }
- errno_t g_tls_t::connect()
- {
- TLS_SESSION_T tls_tmp = tls;
- if (!tls)
- {
- return FAIL;
- }
- if (InterlockedExchangeAdd(&ref, 1) <= 0)
- {
- InterlockedDecrement(&ref);
- error_code = FAIL;
- return FAIL;
- }
- #if USE_TLS_OPENSSL_MEM
- int b = FAIL;
- ssize_t size = 0;
- if (!p_recv || !p_recv_size)
- {
- error_code = FAIL;
- wprintf(L"p_recv or p_recv_size not set\n");
- }
- else
- {
- RECV_MORE:
- if (!SSL_is_init_finished(tls))
- {
- error_code = OK;
- b = SSL_connect(tls);
- if (b <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, b) : FAIL;
- //- wprintf(L"tls.connect::SSL_connect %i %i\n", b, error_code);
- }
- if (
- (error_code == OK) ||
- (error_code == SSL_ERROR_WANT_READ)
- )
- {
- size = tls ? BIO_read(b_send, p_recv, (int)p_recv_size) : FAIL;
- if (size <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- //- wprintf(L"tls.connect::BIO_read %i\n", error_code);
- }
- else
- {
- size = send_raw(p_recv, size);
- if (size <= 0)
- {
- error_code = WSAGetLastError();
- //- wprintf(L"tls.connect::send %i\n", error_code);
- }
- }
- if (
- (error_code == OK) ||
- (error_code == SSL_ERROR_WANT_READ)
- )
- {
- size = ::recv(so, p_recv, (int)p_recv_size, 0);
- if (size <= 0)
- {
- error_code = WSAGetLastError();
- //- wprintf(L"tls.connect::recv %i\n", error_code);
- }
- else
- {
- size = tls ? BIO_write(b_recv, p_recv, (int)size) : FAIL;
- if (size <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- //- wprintf(L"tls.connect::BIO_write %i\n", error_code);
- }
- else
- {
- goto RECV_MORE;
- }
- }
- }
- }
- }
- }
- #else
- int b = SSL_connect(tls_tmp);
- if (b <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, b) : FAIL;
- }
- #endif
- if (!InterlockedDecrement(&ref))
- {
- tls_shutdown(tls_tmp);
- tls_free(tls_tmp);
- }
- return (1 == b) ? OK : FAIL;
- }
- ssize_t g_tls_t::recv(char * msg, size_t count)
- {
- TLS_SESSION_T tls_tmp = tls;
- if (!tls)
- {
- // fall-back to RAW TCP
- return ::recv(so, msg, (int)count, 0);
- }
- if (InterlockedExchangeAdd(&ref, 1) <= 0)
- {
- InterlockedDecrement(&ref);
- error_code = FAIL;
- return FAIL;
- }
- #if USE_TLS_OPENSSL_MEM
- BIO * b_recv_tmp = b_recv;
- ssize_t size = 0;
- RECV_MORE:
- size = tls ? SSL_read(tls, msg, (int)count) : FAIL;
- if (size <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- if (error_code == SSL_ERROR_WANT_READ)
- {
- ssize_t size_read = ::recv(so, msg, (int)count, 0);
- if (size_read <= 0)
- {
- error_code = WSAGetLastError();
- //- wprintf(L"tls.recv::recv %i\n", error_code);
- }
- else
- {
- if (!tls || (0 >= (size_read = BIO_write(b_recv_tmp, msg, (int)size_read))))
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size_read) : FAIL;
- //- wprintf(L"tls.recv::BIO_write %i\n", error_code);
- }
- else
- {
- goto RECV_MORE;
- }
- }
- }
- }
- #else
- ssize_t size = tls ? SSL_read(tls_tmp, msg, (int)count) : FAIL;
- if (size <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- }
- #endif
- if (!InterlockedDecrement(&ref))
- {
- tls_shutdown(tls_tmp);
- tls_free(tls_tmp);
- }
- return size;
- }
- ssize_t g_tls_t::send(const char * msg, size_t count)
- {
- TLS_SESSION_T tls_tmp = tls;
- if (!tls)
- {
- // fall-back to RAW TCP
- return send_raw(msg, count);
- }
- if (InterlockedExchangeAdd(&ref, 1) <= 0)
- {
- InterlockedDecrement(&ref);
- error_code = FAIL;
- return FAIL;
- }
- #if USE_TLS_OPENSSL_MEM
- BIO * b_send_tmp = b_send;
- const char * p = msg;
- size_t remain = count;
- SEND_MORE:
- ssize_t size = (remain > MAX_TLS_GROUP) ? MAX_TLS_GROUP : remain;
- size = tls ? SSL_write(tls_tmp, p, (int)size) : FAIL;
- if (size <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- //- wprintf(L"tls.send::SSL_write %i\n", error_code);
- }
- else
- {
- p += size;
- remain -= size;
- BUF_MEM * bm = NULL;
- BIO_get_mem_ptr(b_send_tmp, &bm);
- if (!bm)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- //- wprintf(L"tls.send::tls_bio_get_mem_ptr %i\n", error_code);
- }
- else
- {
- size = send_raw(bm->data, bm->length);
- #if USE_TLS_OPENSSL
- bm->length = 0;
- BIO_set_shutdown(b_send_tmp, BIO_NOCLOSE);
- BIO_set_mem_buf(b_send_tmp, bm, BIO_CLOSE);
- #else
- BIO_reset(b_send_tmp);
- #endif
- if (size > 0)
- {
- if (remain)
- {
- goto SEND_MORE;
- }
- size = count;
- }
- }
- }
- #else
- ssize_t size = tls ? SSL_write(tls_tmp, msg, (int)count) : FAIL;
- if (size <= 0)
- {
- error_code = tls ? SSL_get_error(tls_tmp, (int)size) : FAIL;
- }
- #endif
- if (!InterlockedDecrement(&ref))
- {
- tls_shutdown(tls_tmp);
- tls_free(tls_tmp);
- }
- return size;
- }
Add Comment
Please, Sign In to add comment