From e94c3fa64c396f3383639c15de73a3dbc09a03b1 Mon Sep 17 00:00:00 2001 From: timoreo Date: Sun, 10 Dec 2023 17:59:17 +0100 Subject: [PATCH] Device refcouting --- src/main.cpp | 101 ++++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 272f26f..dd8bc49 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,10 +7,10 @@ #include #include #include +#include "olm/base64.hh" #define PREFIX_DIRECTORY "./matrix-storage" #define TOKEN_FILENAME "token" -#define DEVICE_ID "XREVXEDLHU" class Store : public Matrix::Store { void setSyncToken(std::string token) override {} //TODO store in file @@ -18,6 +18,11 @@ 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() { @@ -57,16 +62,22 @@ void generate_fallback_key(olm::Account& acc) { // 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(); - std::string signature(signlen, '\0'); - acc.sign(reinterpret_cast(jsonStr), strlen(jsonStr), reinterpret_cast(signature.data()), signlen); + 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(); - json_object_set(signitem, ("ed25519:" + client.getDeviceId()).c_str(), json_stringn(signature.data(), signlen)); + 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(signobj, client.getUserId().c_str(), signitem); - json_object_set(json, "signatures", signobj); + 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(); @@ -94,10 +105,10 @@ json_t* get_device_keys(Matrix::Client& client, olm::Account& acc) { 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_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) { @@ -114,12 +125,12 @@ json_t* get_fallback_keys(Matrix::Client& client, olm::Account& acc) { const char* keyid = json_object_iter_key(iter); json_t* keyval = json_object_iter_value(iter); json_t* tosign = json_object(); - json_object_set_new(tosign, "key", keyval); + 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_new(fallback_keys, (std::string("signed_curve25519:") + keyid).c_str(), tosign); + json_object_set(fallback_keys, (std::string("signed_curve25519:") + keyid).c_str(), tosign); iter = json_object_iter_next(keyobj, iter); } json_decref(keys); @@ -141,10 +152,10 @@ json_t* get_unpublished_otk(Matrix::Client& client, olm::Account& acc) { const char* keyid = json_object_iter_key(iter); json_t* keyval = json_object_iter_value(iter); json_t* tosign = json_object(); - json_object_set_new(tosign, "key", keyval); + json_object_set(tosign, "key", keyval); sign_json(client, acc, tosign); - json_object_set_new(otk_keys, (std::string("signed_curve25519:") + keyid).c_str(), tosign); + json_object_set(otk_keys, (std::string("signed_curve25519:") + keyid).c_str(), tosign); iter = json_object_iter_next(keyobj, iter); } json_decref(keys); @@ -160,6 +171,36 @@ void save_keys(olm::Account& acc) { 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); @@ -175,38 +216,8 @@ void load_account(Matrix::Client& client, olm::Account& acc) { // Fallback keys generate_fallback_key(acc); std::cout << "Generated fallback key" << std::endl; + upload_keys(client, acc); - // Convert to pickled format - // 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); - acc.mark_keys_as_published(); - // Whether a key or not is published is saved, let's save again - save_keys(acc); } else { // Load from file std::ifstream::pos_type fsize = ifs.tellg(); @@ -247,7 +258,7 @@ int main() { if (!stream.is_open()) { // File dosn't exist, log in - if (client.login("timoreo-3ds", ask_for_pass(), DEVICE_ID)) { + if (client.login("timoreo-3ds", ask_for_pass())) { // logged in puts("Logged in !!"); std::ofstream ostr{ TOKEN_FILENAME, std::fstream::out };