From 0fc3f95c9b0a5a2c1e74dfca882801e62c97a095 Mon Sep 17 00:00:00 2001 From: timoreo Date: Sun, 10 Dec 2023 20:24:32 +0100 Subject: [PATCH] Move encryption code over to SDK --- src/main.cpp | 207 +-------------------------------------------------- 1 file changed, 1 insertion(+), 206 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index dd8bc49..2ef191a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,12 +2,9 @@ #include #include #include -#include #include #include #include -#include -#include "olm/base64.hh" #define PREFIX_DIRECTORY "./matrix-storage" #define TOKEN_FILENAME "token" @@ -18,11 +15,6 @@ class Store : public Matrix::Store { void setFilterId(std::string filterId) override {} std::string getFilterId() override { return ""; } }; -void print_json(json_t *json){ - char* data = json_dumps(json, 0); - puts(data); - free(data); -} PrintConsole* bottom = new PrintConsole; std::string ask_for_pass() { @@ -35,202 +27,6 @@ std::string ask_for_pass() { swkbdInputText(&swkbd, buf, sizeof(buf)); return buf; } -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); - acc.generate_one_time_keys(otkcount, otkrandom.get(), len); -} -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(olm::Account& acc) { - size_t len = acc.new_account_random_length(); - std::unique_ptr random = std::make_unique(len); - PS_GenerateRandomBytes(random.get(), len); - acc.new_account(random.get(), 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); - 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, olm::Account& acc, json_t* json) { - puts("Signing json"); - char* jsonStr = json_dumps(json, JSON_COMPACT | JSON_SORT_KEYS); - size_t signlen = acc.signature_length(); - size_t ptrlen = olm::encode_base64_length(signlen); - std::unique_ptr signature = std::make_unique(ptrlen); - acc.sign(reinterpret_cast(jsonStr), strlen(jsonStr), signature.get() + ptrlen - signlen, signlen); - free(jsonStr); - - olm::encode_base64(signature.get() + ptrlen - signlen, signlen, signature.get()); - - json_t* signitem = json_object(); - std::cout << std::string(reinterpret_cast(signature.get()), ptrlen) << std::endl; - json_object_set_new(signitem, ("ed25519:" + client.getDeviceId()).c_str(), json_stringn(reinterpret_cast(signature.get()), ptrlen)); - json_t* signobj = json_object(); - json_object_set_new(signobj, client.getUserId().c_str(), signitem); - json_object_set_new(json, "signatures", signobj); -} -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")); - json_array_append_new(algorithms, json_string("m.megolm.v1.aes-sha2")); - json_object_set_new(device_keys, "algorithms", algorithms); - json_object_set_new(device_keys, "device_id", json_string(client.getDeviceId().c_str())); - json_object_set_new(device_keys, "user_id", json_string(client.getUserId().c_str())); - - // Extract keys - 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(device_keys, ("ed25519:" + client.getDeviceId()).c_str(), json_object_get(keys, "ed25519")); - json_object_set(device_keys, ("curve25519:" + client.getDeviceId()).c_str(), json_object_get(keys, "curve25519")); - json_decref(keys); - std::cout << "Finalizing" << std::endl; - return device_keys; -} -json_t* get_fallback_keys(Matrix::Client& client, olm::Account& acc) { - json_t* fallback_keys = json_object(); - // Extract keys - 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); - - while (iter != nullptr) { - const char* keyid = json_object_iter_key(iter); - json_t* keyval = json_object_iter_value(iter); - json_t* tosign = json_object(); - json_object_set(tosign, "key", keyval); - // object is fallback key - json_object_set_new(tosign, "fallback", json_true()); - - sign_json(client, acc, tosign); - json_object_set(fallback_keys, (std::string("signed_curve25519:") + keyid).c_str(), tosign); - iter = json_object_iter_next(keyobj, iter); - } - json_decref(keys); - return fallback_keys; -} - -json_t* get_unpublished_otk(Matrix::Client& client, olm::Account& acc) { - json_t* otk_keys = json_object(); - // Extract keys - 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); - - while (iter != nullptr) { - const char* keyid = json_object_iter_key(iter); - json_t* keyval = json_object_iter_value(iter); - json_t* tosign = json_object(); - json_object_set(tosign, "key", keyval); - - sign_json(client, acc, tosign); - json_object_set(otk_keys, (std::string("signed_curve25519:") + keyid).c_str(), tosign); - iter = json_object_iter_next(keyobj, iter); - } - json_decref(keys); - return otk_keys; -} - -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.get(), pacclen, 1, file); - fclose(file); -} - -void upload_keys(Matrix::Client& client, olm::Account& acc) { // 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_new(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_new(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_new(upload_keys, "one_time_keys", otk); - - client.uploadKeys(upload_keys); - std::cout << "Keys uploaded !" << std::endl; - print_json(upload_keys); - json_decref(upload_keys); - acc.mark_keys_as_published(); - // Whether a key or not is published is saved, let's save again - save_keys(acc); -} -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()) { - 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; - upload_keys(client, acc); - - } else { - // Load from file - std::ifstream::pos_type fsize = ifs.tellg(); - if (fsize == -1) { - std::cout << "What." << std::endl; - return; - } - auto data = std::make_unique(fsize); - ifs.seekg(0, std::ios::beg); - ifs.read(reinterpret_cast(data.get()), static_cast(fsize)); - olm::unpickle(data.get(), data.get() + fsize, acc); - } -} int main() { fsInit(); @@ -244,7 +40,6 @@ int main() { // Matrix::MemoryStore store{}; Matrix::Client client("https://matrix.timoreo.fr", "", nullptr); - auto acc = std::make_unique(); while (aptMainLoop()) { gspWaitForVBlank(); hidScanInput(); @@ -282,7 +77,7 @@ int main() { } std::cout << "Logged in as " << userid << std::endl; // Load encryption here - load_account(client, *acc); + client.start_encryption(); client.setRoomInfoCallback([](std::string roomId, Matrix::RoomInfo info) { consoleSelect(bottom); printf("Joined room %s named %s\n", roomId.c_str(), info.name.c_str());