#include "VoidNet_LL/SecureSocket.hpp" #include namespace inl::net::sockets { /*SecureSocket::SecureSocket() : m_context(0), m_conn(0), m_eof(false) { m_socket = make_unique(SocketType::Streaming); // Intitialize the SSL client-side socket SSL_library_init(); SSL_load_error_strings(); ERR_load_BIO_strings(); } bool SecureSocket::Connect(const IPAddress & addrStr) { if (!m_context) { m_context = SSL_CTX_new(SSLv23_client_method()); assert(m_context); } if (!m_conn) { m_conn = SSL_new(m_context); assert(m_conn); m_in = BIO_new(BIO_s_mem()); m_out = BIO_new(BIO_s_mem()); SSL_set_bio(m_conn, m_in, m_out); SSL_set_connect_state(m_conn); } return m_socket->Connect(addrStr); } bool SecureSocket::Close() const { return m_socket->Close(); } bool SecureSocket::HasPendingData(uint32_t & pendingDataSize) const { return m_socket->HasPendingData(pendingDataSize); } bool SecureSocket::Send(byte* data, int32_t count, int32_t &sent, int flags) { sent = SSL_write(m_conn, data, count); SendFromBio(); // Write data if available if (sent < 0) { HandleReturn(sent); return true; } return sent > 0; } bool SecureSocket::SendRaw(byte * buf, size_t len, int flags) { int32_t sent; return m_socket->Send(buf, len, sent) && sent == len; } bool SecureSocket::SendFromBio(int flags) { byte buf[4096]; size_t pending = BIO_ctrl_pending(m_out); if (!pending) return true; size_t bytes = BIO_read(m_out, buf, sizeof(buf)); if (bytes > 0) return SendRaw(buf, bytes, flags); else if (bytes == -1 || bytes == 0) return true; return false; } bool SecureSocket::RecvToBio(int flags) { byte buf[4096]; size_t bytes = m_socket->Recv(buf, sizeof(buf), flags); if (bytes > 0) { size_t written = BIO_write(m_in, buf, int(bytes)); assert(bytes == written); return true; } else if (bytes == 0) { // No data m_eof = true; return true; } return false; } void SecureSocket::HandleReturn(size_t ret) { int32_t err = SSL_get_error(m_conn, ret); if (SSL_ERROR_WANT_WRITE == err) SendFromBio(); else if (SSL_ERROR_WANT_READ == err) RecvToBio(); else if (SSL_ERROR_SSL == err) throw inl::RuntimeException(); else assert(!"unexpected error"); } bool SecureSocket::Recv(byte* data, int32_t count, int32_t &read, int flags) { read = SSL_read(m_conn, data, count); if (read < 0) { HandleReturn(read); if (m_eof) return false; } return read > 0; } bool SecureSocket::Wait(SocketWaitConditions cond, chrono::milliseconds t) const { return m_socket->Wait(cond, t); } SocketConnectionState SecureSocket::GetConnectionState() const { return m_socket->GetConnectionState(); } void SecureSocket::GetAddress(IPAddress & outAddr) const { m_socket->GetAddress(outAddr); } int32_t SecureSocket::GetPort() const { return m_socket->GetPort(); } void SecureSocket::UseCertificateFile(string const & path) { if (!m_context) assert(!"not initialized yet"); if (SSL_CTX_use_certificate_file(m_context, path.c_str(), SSL_FILETYPE_PEM) <= 0) throw inl::RuntimeException(); } void SecureSocket::UsePrivateKeyFile(string const & path) { if (!m_context) assert(!"not initialized yet"); if (SSL_CTX_use_PrivateKey_file(m_context, path.c_str(), SSL_FILETYPE_PEM) <= 0) throw inl::RuntimeException(); if (!SSL_CTX_check_private_key(m_context)) throw inl::RuntimeException(); }*/ }