From c9dfadb1b667b125106b75907ec8adb10f7923d8 Mon Sep 17 00:00:00 2001 From: timoreo Date: Sat, 9 Dec 2023 23:35:38 +0100 Subject: [PATCH] Fix : various memory errors + reformat to be better C++ code --- CMakeLists.txt | 1 + src/main.cpp | 143 ++++++++++++++++++++++++++----------------------- 2 files changed, 77 insertions(+), 67 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17b5f2d..349a59e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.24) project(matrix-3ds-client) # for compiling a part of the pica asm enable_language(ASM) +add_compile_options(-O2 -Wall -Wextra -pedantic -Wno-unused-parameter) add_subdirectory(matrix-3ds-sdk) add_subdirectory(olm) diff --git a/src/main.cpp b/src/main.cpp index 83b747b..e9a07b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ #include <3ds.h> #include -#include #include +#include #include #include #include @@ -22,7 +22,6 @@ class Store : public Matrix::Store { void setFilterId(std::string filterId) override {} std::string getFilterId() override { return ""; } }; -std::string ask_for_pass(); PrintConsole* bottom = new PrintConsole; std::string ask_for_pass() { @@ -31,50 +30,50 @@ std::string ask_for_pass() { swkbdSetValidation(&swkbd, SWKBD_NOTEMPTY_NOTBLANK, 0, 0); swkbdSetPasswordMode(&swkbd, SWKBD_PASSWORD_HIDE_DELAY); swkbdSetHintText(&swkbd, "Enter password"); - char buf[256]; + char buf[256]{0}; swkbdInputText(&swkbd, buf, sizeof(buf)); return buf; } -void generate_otk(OlmAccount* acc, size_t otkcount) { - size_t len = olm_account_generate_one_time_keys_random_length(acc, otkcount); - std::unique_ptr otkrandom = std::make_unique(len); +void generate_otk(olm::Account& acc, size_t otkcount) { + size_t len = acc.generate_one_time_keys_random_length(otkcount); + std::unique_ptr otkrandom = std::make_unique(len); PS_GenerateRandomBytes(otkrandom.get(), len); - olm_account_generate_one_time_keys(acc, otkcount, otkrandom.get(), len); + acc.generate_one_time_keys(otkcount, otkrandom.get(), len); } -void generate_otk(OlmAccount* acc){ - size_t otkcount = olm_account_max_number_of_one_time_keys(acc)/2; +void generate_otk(olm::Account& acc){ + size_t otkcount = acc.max_number_of_one_time_keys()/2; generate_otk(acc, otkcount); } -void generate_device_key(OlmAccount* acc) { - size_t len = olm_create_account_random_length(acc); - std::unique_ptr random = std::make_unique(len); +void generate_device_key(olm::Account& acc) { + size_t len = acc.new_account_random_length(); + std::unique_ptr random = std::make_unique(len); PS_GenerateRandomBytes(random.get(), len); - olm_create_account(acc, random.get(), len); + acc.new_account(random.get(), len); } -void generate_fallback_key(OlmAccount* acc) { - size_t len = olm_account_generate_fallback_key_random_length(acc); - std::unique_ptr random = std::make_unique(len); +void generate_fallback_key(olm::Account& acc) { + size_t len = acc.generate_fallback_key_random_length(); + std::unique_ptr random = std::make_unique(len); PS_GenerateRandomBytes(random.get(), len); - olm_account_generate_fallback_key(acc, random.get(), len); + acc.generate_fallback_key(random.get(), len); } // Make sure to remove any unsigned and signatures block before doing this ! -void sign_json(Matrix::Client& client, OlmAccount* acc, json_t* json) { +void sign_json(Matrix::Client& client, olm::Account& acc, json_t* json) { char* jsonStr = json_dumps(json, JSON_COMPACT | JSON_SORT_KEYS); - size_t signlen = olm_account_signature_length(acc); - char* signature = reinterpret_cast(malloc(signlen)); - olm_account_sign(acc, jsonStr, strlen(jsonStr), signature, signlen); + size_t signlen = acc.signature_length(); + std::string signature(signlen, '\0'); + acc.sign(reinterpret_cast(jsonStr), strlen(jsonStr), reinterpret_cast(signature.data()), signlen); free(jsonStr); json_t * signitem = json_object(); - json_object_set(signitem, ("ed25519:" + client.getDeviceId()).c_str(), json_stringn(signature, signlen)); + json_object_set(signitem, ("ed25519:" + client.getDeviceId()).c_str(), json_stringn(signature.data(), signlen)); json_t * signobj = json_object(); json_object_set(signobj, client.getUserId().c_str(), signitem); json_object_set(json, "signatures", signobj); } -json_t* get_device_keys(Matrix::Client& client, OlmAccount* acc) { +json_t* get_device_keys(Matrix::Client& client, olm::Account& acc) { json_t * device_keys = json_object(); json_t * algorithms = json_array(); json_array_append_new(algorithms, json_string("m.olm.v1.curve25519-aes-sha2")); @@ -84,26 +83,35 @@ json_t* get_device_keys(Matrix::Client& client, OlmAccount* acc) { json_object_set_new(device_keys, "user_id", json_string(client.getUserId().c_str())); // Extract keys - size_t acclen = olm_account_identity_keys_length(acc); - auto acckeys = reinterpret_cast(malloc(acclen)); - olm_account_identity_keys(acc, acckeys, acclen); - json_t * keys = json_loads(acckeys, 0, nullptr); - free(acckeys); + size_t acclen = acc.get_identity_json_length(); + std::unique_ptr acckeys = std::make_unique(acclen); + size_t bytes = acc.get_identity_json(acckeys.get(), acclen); + std::cout << "Parsing bytes" << std::endl; + json_error_t error; + sleep(5); + std::cout << "Heading into it..." << std::endl; + json_t * keys = json_loadb(reinterpret_cast(acckeys.get()), bytes, 0, &error); + if(keys == nullptr){ + printf("error: on line %d at char %d: %s\n", error.line, error.column ,error.text); + sleep(10); + } + std::cout << "Reloaded data" << std::endl; + std::cout << "Adding bits" << std::endl; // Merge keys json_object_set_new(device_keys, ("ed25519:" + client.getDeviceId()).c_str(), json_object_get(keys, "ed25519")); json_object_set_new(device_keys, ("curve25519:" + client.getDeviceId()).c_str(), json_object_get(keys, "curve25519")); + std::cout << "Finalizing" << std::endl; json_decref(keys); return device_keys; } -json_t* get_fallback_keys(Matrix::Client& client, OlmAccount* acc) { +json_t* get_fallback_keys(Matrix::Client& client, olm::Account& acc) { json_t * fallback_keys = json_object(); // Extract keys - size_t acclen = olm_account_unpublished_fallback_key_length(acc); - auto acckeys = reinterpret_cast(malloc(acclen)); - olm_account_unpublished_fallback_key(acc, acckeys, acclen); - json_t * keys = json_loads(acckeys, 0, nullptr); - free(acckeys); + size_t acclen = acc.get_unpublished_fallback_key_json_length(); + auto acckeys = std::make_unique(acclen); + size_t bytes = acc.get_unpublished_fallback_key_json(acckeys.get(), acclen); + json_t * keys = json_loadb(reinterpret_cast(acckeys.get()), bytes, 0, nullptr); json_t* keyobj = json_object_get(keys, "curve25519"); void* iter = json_object_iter(keyobj); @@ -123,14 +131,13 @@ json_t* get_fallback_keys(Matrix::Client& client, OlmAccount* acc) { return fallback_keys; } -json_t* get_unpublished_otk(Matrix::Client& client, OlmAccount* acc) { +json_t* get_unpublished_otk(Matrix::Client& client, olm::Account& acc) { json_t * otk_keys = json_object(); // Extract keys - size_t acclen = olm_account_one_time_keys_length(acc); - auto acckeys = reinterpret_cast(malloc(acclen)); - olm_account_one_time_keys(acc, acckeys, acclen); - json_t * keys = json_loads(acckeys, 0, nullptr); - free(acckeys); + size_t acclen = acc.get_one_time_keys_json_length(); + auto acckeys = std::make_unique(acclen); + size_t bytes = acc.get_one_time_keys_json(acckeys.get(), acclen); + json_t * keys = json_loadb(reinterpret_cast(acckeys.get()), bytes, 0, nullptr); json_t* keyobj = json_object_get(keys, "curve25519"); void* iter = json_object_iter(keyobj); @@ -149,55 +156,60 @@ json_t* get_unpublished_otk(Matrix::Client& client, OlmAccount* acc) { return otk_keys; } -void save_keys(OlmAccount* acc) { - size_t pacclen = olm_pickle_account_length(acc); - auto m = reinterpret_cast(malloc(pacclen)); - olm_pickle_account(acc, nullptr, 0, m, pacclen); - pacclen = _olm_decode_base64(m, pacclen, m); +void save_keys(olm::Account& acc) { + size_t pacclen = olm::pickle_length(acc); + auto m = std::make_unique(pacclen); + olm::pickle(m.get(), acc); FILE* file = fopen("secret-keys", "w"); - fwrite(m, pacclen, 1, file); - free(m); + fwrite(m.get(), pacclen, 1, file); fclose(file); } -OlmAccount* load_account(Matrix::Client& client){ - auto* acc = static_cast(malloc(olm_account_size())); - olm_account(acc); - std::filebuf filestorage; +void load_account(Matrix::Client& client, olm::Account& acc){ // std::FILE* file = std::fopen("secret-keys", "r"); std::ifstream ifs("secret-keys", std::ios::binary|std::ios::ate); - if (ifs.is_open()) { + if (!ifs.is_open()) { + std::cout << "No secret keys found, generating " << std::endl; // Generate and save to file // Device keys generate_device_key(acc); + std::cout << "Generated device key" << std::endl; // One time keys generate_otk(acc); + std::cout << "Generated OTK key" << std::endl; // Fallback keys generate_fallback_key(acc); + std::cout << "Generated fallback key" << std::endl; // Convert to pickled format - save_keys(acc); + // save_keys(acc); + std::cout << "Saved keys postgen." << std::endl; // Upload the keys --- // Build device key json json_t * upload_keys = json_object(); json_t* device_keys = get_device_keys(client, acc); + std::cout << "Gathered device keys" << std::endl; // Sign keys block sign_json(client, acc, device_keys); + std::cout << "Signed device keys" << std::endl; json_object_set(upload_keys, "device_keys", device_keys); json_t* fallback_keys = get_fallback_keys(client, acc); + std::cout << "Signed fallback keys" << std::endl; // fallback keys are already signed json_object_set(upload_keys, "fallback_keys", fallback_keys); // OTK keys json_t* otk = get_unpublished_otk(client, acc); + std::cout << "Signed OTK keys" << std::endl; // OTK keys are already signed json_object_set(upload_keys, "one_time_keys", otk); client.uploadKeys(upload_keys); + std::cout << "Keys uploaded !" << std::endl; json_decref(upload_keys); - olm_account_mark_keys_as_published(acc); + acc.mark_keys_as_published(); // Whether a key or not is published is saved, let's save again save_keys(acc); } else { @@ -205,16 +217,13 @@ OlmAccount* load_account(Matrix::Client& client){ std::ifstream::pos_type fsize = ifs.tellg(); if(fsize == -1){ std::cout << "What." << std::endl; - return acc; + return; } - size_t overhead = fsize/4; - auto data = reinterpret_cast(malloc(overhead + fsize)); + auto data = std::make_unique(fsize); ifs.seekg(0, std::ios::beg); - ifs.read(reinterpret_cast(overhead + data), static_cast(fsize)); - _olm_encode_base64(overhead + data, fsize, data); - olm_unpickle_account(acc, nullptr, 0, data, overhead + fsize); + ifs.read(reinterpret_cast(data.get()), static_cast(fsize)); + olm::unpickle(data.get(),data.get() + fsize, acc); } - return acc; } @@ -224,12 +233,13 @@ int main() { consoleInit(GFX_BOTTOM, bottom); uint8_t major, minor, patch; olm_get_library_version(&major, &minor, &patch); - std::cout << "Using olm " << major << "." << minor << "." << patch << std::endl; + std::cout << "Using olm " << std::to_string(major) << "." << std::to_string(minor) << "." << std::to_string(patch) << std::endl; std::filesystem::create_directories(PREFIX_DIRECTORY); chdir(PREFIX_DIRECTORY); - Matrix::MemoryStore store = Matrix::MemoryStore(); - Matrix::Client client("https://matrix.timoreo.fr", "", &store); - OlmAccount* acc; + + // Matrix::MemoryStore store{}; + Matrix::Client client("https://matrix.timoreo.fr", "", nullptr); + auto acc = std::make_unique(); while (aptMainLoop()) { gspWaitForVBlank(); hidScanInput(); @@ -267,7 +277,7 @@ int main() { } std::cout << "Logged in as " << userid << std::endl; // Load encryption here - acc = load_account(client); + load_account(client, *acc); client.setRoomInfoCallback([](std::string roomId, Matrix::RoomInfo info){ consoleSelect(bottom); printf("Joined room %s named %s\n", roomId.c_str(), info.name.c_str()); @@ -284,7 +294,6 @@ int main() { } client.stopSyncLoop(); // DO NOT LOGOUT, KEEP ENCRYPTION KEYS - free(acc); gfxExit(); fsExit(); } \ No newline at end of file