int save_data(Tox *m, const char *path) { if (path == NULL) goto on_error; FILE *fp = fopen(path, "wb"); if (fp == NULL) return -1; size_t data_len = tox_get_savedata_size(m); char *data = malloc(data_len); if (data == NULL) goto on_error; tox_get_savedata(m, (uint8_t *) data); if (fwrite(data, data_len, 1, fp) != 1) { free(data); fclose(fp); goto on_error; } free(data); fclose(fp); return 0; on_error: fprintf(stderr, "Warning: save_data failed\n"); return -1; }
/** * @brief Returns the unencrypted tox save data */ QByteArray Core::getToxSaveData() { uint32_t fileSize = tox_get_savedata_size(tox); QByteArray data; data.resize(fileSize); tox_get_savedata(tox, (uint8_t*)data.data()); return data; }
static void r2tox_save() { struct Tor *t = tox; int sz = tox_get_savedata_size (t); uint8_t *buf = (uint8_t *)calloc (sz, 1); tox_get_savedata (t, buf); printf ("Saving tox.data %d\n", sz); FILE *fd = fopen("tox.data", "w"); fwrite(buf, sz, 1, fd); fclose(fd); }
void Tox_Dispatcher::save_save_data() { std::string sdf = Platform::get_instance()->get_save_data_file(); std::ofstream os; os.open(sdf, std::ios::out | std::ios::binary); if (os.good()) { LOG(INFO) << "Saving tox data"; const size_t len = tox_get_savedata_size(tox); std::vector<uint8_t> save_data(len, 0); tox_get_savedata(tox, save_data.data()); os.write((char *) save_data.data(), len); } os.close(); }
int store_data(Tox *m, const char *path) { if (path == NULL) return -1; FILE *fp = fopen(TEMP_PROFILE_SAVE_NAME, "wb"); if (fp == NULL) return -1; size_t data_len = tox_get_savedata_size(m); char data[data_len]; tox_get_savedata(m, (uint8_t *) data); if (user_password.data_is_encrypted && !arg_opts.unencrypt_data) { size_t enc_len = data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; char enc_data[enc_len]; TOX_ERR_ENCRYPTION err; tox_pass_encrypt((uint8_t *) data, data_len, (uint8_t *) user_password.pass, user_password.len, (uint8_t *) enc_data, &err); if (err != TOX_ERR_ENCRYPTION_OK) { fprintf(stderr, "tox_pass_encrypt() failed with error %d\n", err); fclose(fp); return -1; } if (fwrite(enc_data, enc_len, 1, fp) != 1) { fclose(fp); return -1; } } else { /* data will not be encrypted */ if (fwrite(data, data_len, 1, fp) != 1) { fclose(fp); return -1; } } fclose(fp); if (rename(TEMP_PROFILE_SAVE_NAME, path) != 0) return -1; return 0; }
/* Save tox identity to a file */ static void write_save(Tox *tox) { void *data; uint32_t size; uint8_t path_tmp[512], path_real[512], *p; FILE *file; size = tox_get_savedata_size(tox); data = malloc(size); tox_get_savedata(tox, data); strncpy(path_real, config_path, sizeof(config_path)); p = path_real + strlen(path_real); memcpy(p, "tox_save", sizeof("tox_save")); unsigned int path_len = (p - path_real) + sizeof("tox_save"); memcpy(path_tmp, path_real, path_len); memcpy(path_tmp + (path_len - 1), ".tmp", sizeof(".tmp")); file = fopen((char*)path_tmp, "wb"); if(file) { fwrite(data, size, 1, file); fflush(file); fclose(file); if (rename((char*)path_tmp, (char*)path_real) != 0) { log_printf(L_WARNING, "Failed to rename file. %s to %s deleting and trying again\n", path_tmp, path_real); if(remove((const char *)path_real) < 0) { log_printf(L_WARNING, "Failed to remove old save file %s\n", path_real); } if (rename((char*)path_tmp, (char*)path_real) != 0) { log_printf(L_WARNING, "Saving Failed\n"); } else { log_printf(L_DEBUG, "Saved data\n"); } } else { log_printf(L_DEBUG, "Saved data\n"); } } else { log_printf(L_WARNING, "Could not open save file\n"); } free(data); }
void CToxProto::SaveToxProfile(CToxThread *toxThread) { mir_cslock locker(profileLock); if (!toxThread) return; size_t size = tox_get_savedata_size(toxThread->Tox()); uint8_t *data = (uint8_t*)mir_calloc(size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH); tox_get_savedata(toxThread->Tox(), data); pass_ptrA password(mir_utf8encodeW(pass_ptrT(getTStringA("Password")))); if (password && mir_strlen(password)) { TOX_ERR_ENCRYPTION coreEncryptError; if (!tox_pass_encrypt(data, size, (uint8_t*)(char*)password, mir_strlen(password), data, &coreEncryptError)) { debugLogA(__FUNCTION__": failed to encrypt tox profile"); mir_free(data); return; } size += TOX_PASS_ENCRYPTION_EXTRA_LENGTH; } ptrT profilePath(GetToxProfilePath()); FILE *profile = _tfopen(profilePath, _T("wb")); if (profile == NULL) { debugLogA(__FUNCTION__": failed to open tox profile"); mir_free(data); return; } size_t written = fwrite(data, sizeof(char), size, profile); if (size != written) { debugLogA(__FUNCTION__": failed to write tox profile"); } fclose(profile); mir_free(data); }
void CToxProto::SaveToxProfile() { mir_cslock locker(profileLock); size_t size = tox_get_savedata_size(tox); uint8_t *data = (uint8_t*)mir_calloc(size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH); tox_get_savedata(tox, data); size_t passwordLen = mir_strlen(password); if (password && passwordLen) { TOX_ERR_ENCRYPTION coreEncryptError; if (!tox_pass_encrypt(data, size, (uint8_t*)password, passwordLen, data, &coreEncryptError)) { debugLogA(__FUNCTION__": failed to encrypt tox profile"); mir_free(data); return; } size += TOX_PASS_ENCRYPTION_EXTRA_LENGTH; } std::tstring profilePath = GetToxProfilePath(); FILE *profile = _tfopen(profilePath.c_str(), _T("wb")); if (profile == NULL) { debugLogA(__FUNCTION__": failed to open tox profile"); mir_free(data); return; } size_t written = fwrite(data, sizeof(char), size, profile); if (size != written) { debugLogA(__FUNCTION__": failed to write tox profile"); } fclose(profile); mir_free(data); }
void Core::saveConfiguration(const QString& path) { if (QThread::currentThread() != coreThread) return (void) QMetaObject::invokeMethod(this, "saveConfiguration", Q_ARG(const QString&, path)); if (!isReady()) { qWarning() << "saveConfiguration: Tox not started, aborting!"; return; } QSaveFile configurationFile(path); if (!configurationFile.open(QIODevice::WriteOnly)) { qCritical() << "File " << path << " cannot be opened"; return; } qDebug() << "writing tox_save to " << path; uint32_t fileSize = tox_get_savedata_size(tox); bool encrypt = Settings::getInstance().getEncryptTox(); if (fileSize > 0 && fileSize <= std::numeric_limits<int32_t>::max()) { uint8_t *data = new uint8_t[fileSize]; if (encrypt) { if (!pwsaltedkeys[ptMain]) { // probably zero chance event GUI::showWarning(tr("NO Password"), tr("Local file encryption is enabled, but there is no password! It will be disabled.")); Settings::getInstance().setEncryptTox(false); tox_get_savedata(tox, data); } else { tox_get_savedata(tox, data); uint8_t* newData = new uint8_t[fileSize+TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; if (tox_pass_key_encrypt(data, fileSize, pwsaltedkeys[ptMain], newData, nullptr)) { delete[] data; data = newData; fileSize+=TOX_PASS_ENCRYPTION_EXTRA_LENGTH; } else { delete[] newData; delete[] data; qCritical() << "Core::saveConfiguration(QString): Encryption failed, couldn't save"; configurationFile.cancelWriting(); return; } } } else { tox_get_savedata(tox, data); } configurationFile.write(reinterpret_cast<char *>(data), fileSize); configurationFile.commit(); delete[] data; } Settings::getInstance().save(); }
static void test_one(void) { uint8_t name[TOX_MAX_NAME_LENGTH]; uint8_t status_message[TOX_MAX_STATUS_MESSAGE_LENGTH]; uint8_t name2[TOX_MAX_NAME_LENGTH]; uint8_t status_message2[TOX_MAX_STATUS_MESSAGE_LENGTH]; uint32_t index[] = { 1, 2 }; Tox *tox1 = tox_new_log(nullptr, nullptr, &index[0]); set_random_name_and_status_message(tox1, name, status_message); Tox *tox2 = tox_new_log(nullptr, nullptr, &index[1]); set_random_name_and_status_message(tox2, name2, status_message2); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox1, address); Tox_Err_Friend_Add error; uint32_t ret = tox_friend_add(tox1, address, (const uint8_t *)"m", 1, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_OWN_KEY, "Adding own address worked."); tox_self_get_address(tox2, address); uint8_t message[TOX_MAX_FRIEND_REQUEST_LENGTH + 1]; ret = tox_friend_add(tox1, address, nullptr, 0, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_NULL, "Sending request with no message worked."); ret = tox_friend_add(tox1, address, message, 0, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_NO_MESSAGE, "Sending request with no message worked."); ret = tox_friend_add(tox1, address, message, sizeof(message), &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_TOO_LONG, "TOX_MAX_FRIEND_REQUEST_LENGTH is too big."); address[0]++; ret = tox_friend_add(tox1, address, (const uint8_t *)"m", 1, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_BAD_CHECKSUM, "Adding address with bad checksum worked."); tox_self_get_address(tox2, address); ret = tox_friend_add(tox1, address, message, TOX_MAX_FRIEND_REQUEST_LENGTH, &error); ck_assert_msg(ret == 0 && error == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend."); ret = tox_friend_add(tox1, address, message, TOX_MAX_FRIEND_REQUEST_LENGTH, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_ALREADY_SENT, "Adding friend twice worked."); tox_self_set_name(tox1, name, sizeof(name), nullptr); ck_assert_msg(tox_self_get_name_size(tox1) == sizeof(name), "Can't set name of TOX_MAX_NAME_LENGTH"); tox_self_set_status_message(tox1, status_message, sizeof(status_message), nullptr); ck_assert_msg(tox_self_get_status_message_size(tox1) == sizeof(status_message), "Can't set status message of TOX_MAX_STATUS_MESSAGE_LENGTH"); tox_self_get_address(tox1, address); size_t save_size = tox_get_savedata_size(tox1); VLA(uint8_t, data, save_size); tox_get_savedata(tox1, data); tox_kill(tox2); Tox_Err_New err_n; struct Tox_Options *options = tox_options_new(nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, data, save_size); tox2 = tox_new_log(options, &err_n, &index[1]); ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed"); ck_assert_msg(tox_self_get_name_size(tox2) == sizeof name, "Wrong name size."); ck_assert_msg(tox_self_get_status_message_size(tox2) == sizeof status_message, "Wrong status message size"); uint8_t name_loaded[TOX_MAX_NAME_LENGTH] = { 0 }; tox_self_get_name(tox2, name_loaded); ck_assert_msg(!memcmp(name, name_loaded, sizeof name), "Wrong name."); uint8_t status_message_loaded[TOX_MAX_STATUS_MESSAGE_LENGTH] = { 0 }; tox_self_get_status_message(tox2, status_message_loaded); ck_assert_msg(!memcmp(status_message, status_message_loaded, sizeof status_message_loaded), "Wrong status message."); uint8_t address2[TOX_ADDRESS_SIZE] = { 0 }; tox_self_get_address(tox2, address2); ck_assert_msg(memcmp(address2, address, TOX_ADDRESS_SIZE) == 0, "Wrong address."); uint8_t new_name[TOX_MAX_NAME_LENGTH] = { 0 }; tox_self_get_name(tox2, new_name); ck_assert_msg(memcmp(name, new_name, TOX_MAX_NAME_LENGTH) == 0, "Wrong name"); uint8_t sk[TOX_SECRET_KEY_SIZE]; tox_self_get_secret_key(tox2, sk); tox_kill(tox2); tox_options_default(options); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_SECRET_KEY); tox_options_set_savedata_data(options, sk, sizeof(sk)); tox2 = tox_new_log(options, &err_n, &index[1]); ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed"); uint8_t address3[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address3); ck_assert_msg(memcmp(address3, address, TOX_PUBLIC_KEY_SIZE) == 0, "Wrong public key."); uint8_t pk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox2, pk); ck_assert_msg(memcmp(pk, address, TOX_PUBLIC_KEY_SIZE) == 0, "Wrong public key."); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); }
int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Tox *const tox1 = tox_new_log(nullptr, nullptr, nullptr); Tox *const tox2 = tox_new_log(nullptr, nullptr, nullptr); printf("bootstrapping tox2 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); struct test_data to_compare = {{0}}; uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox1, public_key); tox_friend_add_norequest(tox2, public_key, nullptr); tox_self_get_public_key(tox2, public_key); tox_friend_add_norequest(tox1, public_key, nullptr); uint8_t reference_name[TOX_MAX_NAME_LENGTH] = { 0 }; uint8_t reference_status[TOX_MAX_STATUS_MESSAGE_LENGTH] = { 0 }; set_random(tox1, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox2, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox1, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); set_random(tox2, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); tox_self_get_name(tox2, reference_name); tox_self_get_status_message(tox2, reference_status); tox_callback_friend_name(tox1, namechange_callback); tox_callback_friend_status_message(tox1, statuschange_callback); while (true) { if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) && tox_friend_get_connection_status(tox1, 0, nullptr) == TOX_CONNECTION_UDP) { printf("Connected.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, nullptr); c_sleep(tox_iteration_interval(tox1)); } while (true) { if (to_compare.received_name && to_compare.received_status_message) { printf("Exchanged names and status messages.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, nullptr); c_sleep(tox_iteration_interval(tox1)); } size_t save_size = tox_get_savedata_size(tox1); VLA(uint8_t, savedata, save_size); tox_get_savedata(tox1, savedata); struct Tox_Options *const options = tox_options_new(nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, savedata, save_size); Tox *const tox_to_compare = tox_new_log(options, nullptr, nullptr); tox_friend_get_name(tox_to_compare, 0, to_compare.name, nullptr); tox_friend_get_status_message(tox_to_compare, 0, to_compare.status_message, nullptr); ck_assert_msg(memcmp(reference_name, to_compare.name, TOX_MAX_NAME_LENGTH) == 0, "incorrect name: should be all zeroes"); ck_assert_msg(memcmp(reference_status, to_compare.status_message, TOX_MAX_STATUS_MESSAGE_LENGTH) == 0, "incorrect status message: should be all zeroes"); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox_to_compare); return 0; }
int store_data(Tox *m, const char *path) { if (path == NULL) { return -1; } char temp_path[strlen(path) + strlen(TEMP_PROFILE_EXT) + 1]; snprintf(temp_path, sizeof(temp_path), "%s%s", path, TEMP_PROFILE_EXT); FILE *fp = fopen(temp_path, "wb"); if (fp == NULL) { return -1; } size_t data_len = tox_get_savedata_size(m); char *data = malloc(data_len * sizeof(char)); if (data == NULL) { fclose(fp); return -1; } tox_get_savedata(m, (uint8_t *) data); if (user_password.data_is_encrypted && !arg_opts.unencrypt_data) { size_t enc_len = data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; char *enc_data = malloc(enc_len * sizeof(char)); if (enc_data == NULL) { fclose(fp); free(data); return -1; } TOX_ERR_ENCRYPTION err; tox_pass_encrypt((uint8_t *) data, data_len, (uint8_t *) user_password.pass, user_password.len, (uint8_t *) enc_data, &err); if (err != TOX_ERR_ENCRYPTION_OK) { fprintf(stderr, "tox_pass_encrypt() failed with error %d\n", err); fclose(fp); free(data); free(enc_data); return -1; } if (fwrite(enc_data, enc_len, 1, fp) != 1) { fprintf(stderr, "Failed to write profile data.\n"); fclose(fp); free(data); free(enc_data); return -1; } free(enc_data); } else { /* data will not be encrypted */ if (fwrite(data, data_len, 1, fp) != 1) { fprintf(stderr, "Failed to write profile data.\n"); fclose(fp); free(data); return -1; } } fclose(fp); free(data); if (rename(temp_path, path) != 0) { return -1; } return 0; }
int main(int argc, char *argv[]) { Tox *tox1 = tox_new_log(0, 0, 0); Tox *tox2 = tox_new_log(0, 0, 0); struct test_data to_compare = { { 0 } }; uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox1, public_key); tox_friend_add_norequest(tox2, public_key, NULL); tox_self_get_public_key(tox2, public_key); tox_friend_add_norequest(tox1, public_key, NULL); uint8_t reference_name[TOX_MAX_NAME_LENGTH] = { 0 }; uint8_t reference_status[TOX_MAX_STATUS_MESSAGE_LENGTH] = { 0 }; set_random(tox1, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox2, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox1, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); set_random(tox2, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); tox_self_get_name(tox2, reference_name); tox_self_get_status_message(tox2, reference_status); tox_callback_friend_name(tox1, namechange_callback); tox_callback_friend_status_message(tox1, statuschange_callback); while (true) { if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) && tox_friend_get_connection_status(tox1, 0, 0) == TOX_CONNECTION_UDP) { printf("Connected.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, NULL); c_sleep(tox_iteration_interval(tox1)); } while (true) { if (to_compare.received_name && to_compare.received_status_message) { printf("Exchanged names and status messages.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, NULL); c_sleep(tox_iteration_interval(tox1)); } size_t save_size = tox_get_savedata_size(tox1); VLA(uint8_t, savedata, save_size); tox_get_savedata(tox1, savedata); struct Tox_Options *options = tox_options_new(NULL); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, savedata, save_size); Tox *tox_to_compare = tox_new(options, 0); tox_friend_get_name(tox_to_compare, 0, to_compare.name, 0); tox_friend_get_status_message(tox_to_compare, 0, to_compare.status_message, 0); assert(memcmp(reference_name, to_compare.name, TOX_MAX_NAME_LENGTH) == 0); assert(memcmp(reference_status, to_compare.status_message, TOX_MAX_STATUS_MESSAGE_LENGTH) == 0); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox_to_compare); return 0; }
END_TEST START_TEST(test_save_friend) { Tox *tox1 = tox_new(0, 0); Tox *tox2 = tox_new(0, 0); ck_assert_msg(tox1 || tox2, "Failed to create 2 tox instances"); uint32_t to_compare = 974536; tox_callback_friend_request(tox2, accept_friend_request, &to_compare); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); uint32_t test = tox_friend_add(tox1, address, (uint8_t *)"Gentoo", 7, 0); ck_assert_msg(test != UINT32_MAX, "Failed to add friend"); size_t size = tox_get_savedata_size(tox1); uint8_t data[size]; tox_get_savedata(tox1, data); size_t size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t enc_data[size2]; TOX_ERR_ENCRYPTION error1; bool ret = tox_pass_encrypt(data, size, "correcthorsebatterystaple", 25, enc_data, &error1); ck_assert_msg(ret, "failed to encrypted save: %u", error1); ck_assert_msg(tox_is_data_encrypted(enc_data), "magic number missing"); struct Tox_Options options; tox_options_default(&options); options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; options.savedata_data = enc_data; options.savedata_length = size2; TOX_ERR_NEW err2; Tox *tox3 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_LOAD_ENCRYPTED, "wrong error! %u. should fail with %u", err2, TOX_ERR_NEW_LOAD_ENCRYPTED); uint8_t dec_data[size]; TOX_ERR_DECRYPTION err3; ret = tox_pass_decrypt(enc_data, size2, "correcthorsebatterystaple", 25, dec_data, &err3); ck_assert_msg(ret, "failed to decrypt save: %u", err3); options.savedata_data = dec_data; options.savedata_length = size; tox3 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to load from decrypted data: %u", err2); uint8_t address2[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox3, 0, address2, 0); ck_assert_msg(ret, "no friends!"); ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match!"); size = tox_get_savedata_size(tox3); uint8_t data2[size]; tox_get_savedata(tox3, data2); TOX_PASS_KEY key; memcpy(key.salt, salt, 32); memcpy(key.key, known_key2, crypto_box_BEFORENMBYTES); size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t encdata2[size2]; ret = tox_pass_key_encrypt(data2, size, &key, encdata2, &error1); ck_assert_msg(ret, "failed to key encrypt %u", error1); ck_assert_msg(tox_is_data_encrypted(encdata2), "magic number the second missing"); uint8_t out1[size], out2[size]; ret = tox_pass_decrypt(encdata2, size2, pw, pwlen, out1, &err3); ck_assert_msg(ret, "failed to pw decrypt %u", err3); ret = tox_pass_key_decrypt(encdata2, size2, &key, out2, &err3); ck_assert_msg(ret, "failed to key decrypt %u", err3); ck_assert_msg(memcmp(out1, out2, size) == 0, "differing output data"); // and now with the code in use (I only bothered with manually to debug this, and it seems a waste // to remove the manual check now that it's there) options.savedata_data = out1; options.savedata_length = size; Tox *tox4 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to new the third"); uint8_t address5[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox4, 0, address5, 0); ck_assert_msg(ret, "no friends! the third"); ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match! the third"); tox_kill(tox1); tox_kill(tox2); tox_kill(tox3); tox_kill(tox4); }