/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2025 The TokTok team. * Copyright © 2016 Tox project. */ /* * Small test for checking if obtaining savedata, saving it to disk and using * works correctly. */ #include #include #include #include #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "auto_test_support.h" #include "check_compat.h" #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "../toxencryptsave/toxencryptsave.h" static const char *pphrase = "bar"; static const char *name = "foo"; static const char *savefile = "./save"; static void save_data_encrypted(void) { struct Tox_Options *options = tox_options_new(nullptr); ck_assert(options != nullptr); Tox *t = tox_new_log(options, nullptr, nullptr); ck_assert(t != nullptr); tox_options_free(options); tox_self_set_name(t, (const uint8_t *)name, strlen(name), nullptr); FILE *f = fopen(savefile, "wb"); ck_assert(f != nullptr); size_t size = tox_get_savedata_size(t); uint8_t *clear = (uint8_t *)malloc(size); ck_assert(clear != nullptr); /*this function does not write any data at all*/ tox_get_savedata(t, clear); size += TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t *cipher = (uint8_t *)malloc(size); ck_assert(cipher != nullptr); Tox_Err_Encryption eerr; ck_assert_msg(tox_pass_encrypt(clear, size - TOX_PASS_ENCRYPTION_EXTRA_LENGTH, (const uint8_t *)pphrase, strlen(pphrase), cipher, &eerr), "Could not encrypt, error code %d.", eerr); size_t written_value = fwrite(cipher, sizeof(*cipher), size, f); printf("written written_value = %u of %u\n", (unsigned)written_value, (unsigned)size); free(cipher); free(clear); fclose(f); tox_kill(t); } static void load_data_decrypted(void) { FILE *f = fopen(savefile, "rb"); ck_assert(f != nullptr); fseek(f, 0, SEEK_END); int64_t size = ftell(f); fseek(f, 0, SEEK_SET); ck_assert_msg(TOX_PASS_ENCRYPTION_EXTRA_LENGTH <= size && size <= UINT_MAX, "file size out of range"); uint8_t *cipher = (uint8_t *)malloc(size); ck_assert(cipher != nullptr); const size_t clear_size = size - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t *clear = (uint8_t *)malloc(clear_size); ck_assert(clear != nullptr); size_t read_value = fread(cipher, sizeof(*cipher), size, f); printf("Read read_value = %u of %u\n", (unsigned)read_value, (unsigned)size); Tox_Err_Decryption derr; ck_assert_msg(tox_pass_decrypt(cipher, size, (const uint8_t *)pphrase, strlen(pphrase), clear, &derr), "Could not decrypt, error code %s.", tox_err_decryption_to_string(derr)); struct Tox_Options *options = tox_options_new(nullptr); ck_assert(options != nullptr); tox_options_set_experimental_owned_data(options, true); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); ck_assert(tox_options_set_savedata_data(options, clear, clear_size)); free(clear); Tox_Err_New err; Tox *t = tox_new_log(options, &err, nullptr); ck_assert_msg(t != nullptr, "tox_new returned the error value %s", tox_err_new_to_string(err)); tox_options_free(options); uint8_t *readname = (uint8_t *)malloc(tox_self_get_name_size(t)); ck_assert(readname != nullptr); tox_self_get_name(t, readname); ck_assert_msg(memcmp(readname, name, tox_self_get_name_size(t)) == 0, "name returned by tox_self_get_name does not match expected result"); tox_kill(t); free(cipher); free(readname); fclose(f); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); save_data_encrypted(); load_data_decrypted(); ck_assert_msg(remove(savefile) == 0, "Could not remove the savefile."); return 0; }