diff --git a/CMakeLists.txt b/CMakeLists.txt index 69570c9..e940526 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.16) # If MAJOR is 0, and MINOR > 0, Version is BETA project(ColumnLynx - VERSION 0.0.4 + VERSION 0.0.5 LANGUAGES CXX ) diff --git a/include/columnlynx/client/net/tcp/tcp_client.hpp b/include/columnlynx/client/net/tcp/tcp_client.hpp index e6c2273..d27b771 100644 --- a/include/columnlynx/client/net/tcp/tcp_client.hpp +++ b/include/columnlynx/client/net/tcp/tcp_client.hpp @@ -59,6 +59,7 @@ namespace ColumnLynx::Net::TCP { Utils::debug("Newly-Loaded Public Key: " + Utils::bytesToHexString(mLibSodiumWrapper->getPublicKey(), 32)); Utils::debug("Newly-Loaded Private Key: " + Utils::bytesToHexString(mLibSodiumWrapper->getPrivateKey(), 64)); + Utils::debug("Public Encryption Key: " + Utils::bytesToHexString(mLibSodiumWrapper->getXPublicKey(), 32)); } } diff --git a/include/columnlynx/common/libsodium_wrapper.hpp b/include/columnlynx/common/libsodium_wrapper.hpp index 4759cc5..ff4b117 100644 --- a/include/columnlynx/common/libsodium_wrapper.hpp +++ b/include/columnlynx/common/libsodium_wrapper.hpp @@ -130,7 +130,7 @@ namespace ColumnLynx::Utils { std::vector plaintext(len - crypto_aead_chacha20poly1305_ietf_ABYTES); unsigned long long plen = 0; - + if (crypto_aead_chacha20poly1305_ietf_decrypt( plaintext.data(), &plen, nullptr, diff --git a/include/columnlynx/common/utils.hpp b/include/columnlynx/common/utils.hpp index bc690ac..7ac4e59 100644 --- a/include/columnlynx/common/utils.hpp +++ b/include/columnlynx/common/utils.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #ifdef _WIN32 diff --git a/src/client/net/udp/udp_client.cpp b/src/client/net/udp/udp_client.cpp index 225d604..0fb0ca9 100644 --- a/src/client/net/udp/udp_client.cpp +++ b/src/client/net/udp/udp_client.cpp @@ -22,9 +22,12 @@ namespace ColumnLynx::Net::UDP { return; } + //Utils::debug("Using AES key: " + Utils::bytesToHexString(mAesKeyRef->data(), 32)); + auto encryptedPayload = Utils::LibSodiumWrapper::encryptMessage( reinterpret_cast(data.data()), data.size(), *mAesKeyRef, hdr.nonce, "udp-data" + //std::string(reinterpret_cast(&mSessionIDRef), sizeof(uint64_t)) ); std::vector packet; @@ -100,6 +103,7 @@ namespace ColumnLynx::Net::UDP { std::vector plaintext = Utils::LibSodiumWrapper::decryptMessage( ciphertext.data(), ciphertext.size(), *mAesKeyRef, hdr.nonce, "udp-data" + //std::string(reinterpret_cast(&mSessionIDRef), sizeof(uint64_t)) ); if (plaintext.empty()) { diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 4ee4462..c873e22 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -6,20 +6,24 @@ namespace ColumnLynx::Utils { void log(const std::string &msg) { - std::cout << "\033[0m[LOG] " << msg << std::endl; + uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + std::cout << "\033[0m[" << std::to_string(now) << " LOG] " << msg << std::endl; } void warn(const std::string &msg) { - std::cerr << "\033[33m[WARN] " << msg << "\033[0m" << std::endl; + uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + std::cerr << "\033[33m[" << std::to_string(now) << " WARN] " << msg << "\033[0m" << std::endl; } void error(const std::string &msg) { - std::cerr << "\033[31m[ERROR] " << msg << "\033[0m" << std::endl; + uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + std::cerr << "\033[31m[" << std::to_string(now) << " ERROR] " << msg << "\033[0m" << std::endl; } void debug(const std::string &msg) { #if DEBUG || _DEBUG - std::cerr << "\033[95m[DEBUG] " << msg << "\033[0m" << std::endl; + uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + std::cerr << "\033[95m[" << std::to_string(now) << " DEBUG] " << msg << "\033[0m" << std::endl; #else return; #endif @@ -45,7 +49,7 @@ namespace ColumnLynx::Utils { } std::string getVersion() { - return "a0.4"; + return "a0.5"; } unsigned short serverPort() { diff --git a/src/server/server/net/tcp/tcp_connection.cpp b/src/server/server/net/tcp/tcp_connection.cpp index a72c6fd..a2bfcbf 100644 --- a/src/server/server/net/tcp/tcp_connection.cpp +++ b/src/server/server/net/tcp/tcp_connection.cpp @@ -115,9 +115,11 @@ namespace ColumnLynx::Net::TCP { Utils::log("Client protocol version " + std::to_string(clientProtoVer) + " accepted from " + reqAddr + "."); PublicKey signPk; - std::memcpy(signPk.data(), data.data() + 1, std::min(data.size() - 1, sizeof(signPk))); // Store the client's public key (for identification) + std::memcpy(signPk.data(), data.data() + 1, std::min(data.size() - 1, sizeof(signPk))); - crypto_sign_ed25519_pk_to_curve25519(mConnectionPublicKey.data(), signPk.data()); + // We can safely store this without further checking, the client will need to send the encrypted AES key in a way where they must possess the corresponding private key anyways. + crypto_sign_ed25519_pk_to_curve25519(mConnectionPublicKey.data(), signPk.data()); // Store the client's public encryption key key (for identification) + Utils::debug("Client " + reqAddr + " converted public encryption key: " + Utils::bytesToHexString(mConnectionPublicKey.data(), 32)); Utils::debug("Key attempted connect: " + Utils::bytesToHexString(signPk.data(), signPk.size())); @@ -219,7 +221,7 @@ namespace ColumnLynx::Net::TCP { mHandler->sendMessage(ServerMessageType::HANDSHAKE_EXCHANGE_KEY_CONFIRM, Utils::uint8ArrayToString(encryptedPayload.data(), encryptedPayload.size())); // Add to session registry - Utils::log("Handshake with " + reqAddr + " completed successfully. Session ID assigned."); + Utils::log("Handshake with " + reqAddr + " completed successfully. Session ID assigned (" + std::to_string(mConnectionSessionID) + ")."); auto session = std::make_shared(mConnectionAESKey, std::chrono::hours(12), clientIP, htonl(0x0A0A0001), mConnectionSessionID); SessionRegistry::getInstance().put(mConnectionSessionID, std::move(session)); diff --git a/src/server/server/net/udp/udp_server.cpp b/src/server/server/net/udp/udp_server.cpp index 4166570..989f5ee 100644 --- a/src/server/server/net/udp/udp_server.cpp +++ b/src/server/server/net/udp/udp_server.cpp @@ -48,13 +48,17 @@ namespace ColumnLynx::Net::UDP { // Decrypt the actual payload try { + //Utils::debug("Using AES key " + Utils::bytesToHexString(session->aesKey.data(), 32)); + auto plaintext = Utils::LibSodiumWrapper::decryptMessage( encryptedPayload.data(), encryptedPayload.size(), session->aesKey, - hdr->nonce, - "udp-data" + hdr->nonce, "udp-data" + //std::string(reinterpret_cast(&sessionID), sizeof(uint64_t)) ); + Utils::debug("Passed decryption"); + const_cast(session.get())->setUDPEndpoint(mRemoteEndpoint); // Update endpoint after confirming decryption // Update recv counter const_cast(session.get())->recv_ctr.fetch_add(1, std::memory_order_relaxed); @@ -66,8 +70,8 @@ namespace ColumnLynx::Net::UDP { if (mTun) { mTun->writePacket(plaintext); // Send to virtual interface } - } catch (...) { - Utils::warn("UDP: Failed to decrypt payload from " + mRemoteEndpoint.address().to_string()); + } catch (const std::exception &ex) { + Utils::warn("UDP: Failed to process payload from " + mRemoteEndpoint.address().to_string() + " Raw Error: '" + ex.what() + "'"); return; } } @@ -93,6 +97,7 @@ namespace ColumnLynx::Net::UDP { auto encryptedPayload = Utils::LibSodiumWrapper::encryptMessage( reinterpret_cast(data.data()), data.size(), session->aesKey, hdr.nonce, "udp-data" + //std::string(reinterpret_cast(&sessionID), sizeof(uint64_t)) ); std::vector packet;