mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Added function to save an encrypted version of the messenger.
Also added some tests.
This commit is contained in:
parent
83cb946db0
commit
c51b8a9eba
@ -246,6 +246,36 @@ START_TEST(test_large_data)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_large_data_symmetric)
|
||||||
|
{
|
||||||
|
unsigned char k[crypto_secretbox_KEYBYTES];
|
||||||
|
|
||||||
|
unsigned char n[crypto_secretbox_NONCEBYTES];
|
||||||
|
|
||||||
|
unsigned char m1[16 * 16 * 16];
|
||||||
|
unsigned char c1[sizeof(m1) + crypto_box_MACBYTES];
|
||||||
|
unsigned char m1prime[sizeof(m1)];
|
||||||
|
|
||||||
|
int c1len;
|
||||||
|
int m1plen;
|
||||||
|
|
||||||
|
//Generate random messages
|
||||||
|
rand_bytes(m1, sizeof(m1));
|
||||||
|
rand_bytes(n, crypto_box_NONCEBYTES);
|
||||||
|
|
||||||
|
//Generate key
|
||||||
|
new_symmetric_key(k);
|
||||||
|
|
||||||
|
c1len = encrypt_data_symmetric(k, n, m1, sizeof(m1), c1);
|
||||||
|
ck_assert_msg(c1len == sizeof(m1) + crypto_box_MACBYTES, "could not encrypt data");
|
||||||
|
|
||||||
|
m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime);
|
||||||
|
|
||||||
|
ck_assert_msg(m1plen == sizeof(m1), "decrypted text lengths differ");
|
||||||
|
ck_assert_msg(memcmp(m1prime, m1, sizeof(m1)) == 0, "decrypted texts differ");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
#define DEFTESTCASE(NAME) \
|
#define DEFTESTCASE(NAME) \
|
||||||
TCase *NAME = tcase_create(#NAME); \
|
TCase *NAME = tcase_create(#NAME); \
|
||||||
tcase_add_test(NAME, test_##NAME); \
|
tcase_add_test(NAME, test_##NAME); \
|
||||||
@ -263,6 +293,7 @@ Suite *crypto_suite(void)
|
|||||||
DEFTESTCASE(fast_known);
|
DEFTESTCASE(fast_known);
|
||||||
DEFTESTCASE_SLOW(endtoend, 15); /* waiting up to 15 seconds */
|
DEFTESTCASE_SLOW(endtoend, 15); /* waiting up to 15 seconds */
|
||||||
DEFTESTCASE(large_data);
|
DEFTESTCASE(large_data);
|
||||||
|
DEFTESTCASE(large_data_symmetric);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -310,6 +310,27 @@ START_TEST(test_messenger_state_saveloadsave)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_messenger_state_saveload_encrypted)
|
||||||
|
{
|
||||||
|
uint8_t addr[FRIEND_ADDRESS_SIZE];
|
||||||
|
getaddress(m, addr);
|
||||||
|
Messenger *m_temp = new_messenger(TOX_ENABLE_IPV6_DEFAULT);
|
||||||
|
|
||||||
|
size_t size = messenger_size_encrypted(m);
|
||||||
|
uint8_t buffer[size];
|
||||||
|
messenger_save_encrypted(m, buffer, "Gentoo", sizeof("Gentoo"));
|
||||||
|
|
||||||
|
ck_assert_msg(messenger_load_encrypted(m_temp, buffer, size, "Ubuntu", sizeof("Ubuntu")) == -1,
|
||||||
|
"Bad password didn't make the function fail.");
|
||||||
|
ck_assert_msg(messenger_load_encrypted(m_temp, buffer, size, "Gentoo", sizeof("Gentoo")) == 0,
|
||||||
|
"Good password didn't make the function succeed.");
|
||||||
|
uint8_t addr1[FRIEND_ADDRESS_SIZE];
|
||||||
|
getaddress(m_temp, addr1);
|
||||||
|
ck_assert_msg(memcmp(addr1, addr, FRIEND_ADDRESS_SIZE) == 0, "Didn't load messenger successfully");
|
||||||
|
kill_messenger(m_temp);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
#define DEFTESTCASE(NAME) \
|
#define DEFTESTCASE(NAME) \
|
||||||
TCase *tc_##NAME = tcase_create(#NAME); \
|
TCase *tc_##NAME = tcase_create(#NAME); \
|
||||||
tcase_add_test(tc_##NAME, test_##NAME); \
|
tcase_add_test(tc_##NAME, test_##NAME); \
|
||||||
@ -321,6 +342,7 @@ Suite *messenger_suite(void)
|
|||||||
|
|
||||||
DEFTESTCASE(dht_state_saveloadsave);
|
DEFTESTCASE(dht_state_saveloadsave);
|
||||||
DEFTESTCASE(messenger_state_saveloadsave);
|
DEFTESTCASE(messenger_state_saveloadsave);
|
||||||
|
DEFTESTCASE(messenger_state_saveload_encrypted);
|
||||||
|
|
||||||
DEFTESTCASE(getself_name);
|
DEFTESTCASE(getself_name);
|
||||||
DEFTESTCASE(m_get_userstatus_size);
|
DEFTESTCASE(m_get_userstatus_size);
|
||||||
|
@ -2264,6 +2264,75 @@ int messenger_load(Messenger *m, uint8_t *data, uint32_t length)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return the size of data to pass to messenger_save_encrypted(...)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t messenger_size_encrypted(Messenger *m)
|
||||||
|
{
|
||||||
|
return messenger_size(m) + crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the messenger, encrypting the data with key of length key_length
|
||||||
|
*
|
||||||
|
* return 0 on success.
|
||||||
|
* return -1 on failure.
|
||||||
|
*/
|
||||||
|
int messenger_save_encrypted(Messenger *m, uint8_t *data, uint8_t *key, uint16_t key_length)
|
||||||
|
{
|
||||||
|
uint32_t m_size = messenger_size(m);
|
||||||
|
uint8_t *plain_messenger = malloc(m_size);
|
||||||
|
|
||||||
|
if (plain_messenger == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
messenger_save(m, plain_messenger);
|
||||||
|
|
||||||
|
/* Hash the key with SHA256 to get a 32byte key. */
|
||||||
|
uint8_t hash[crypto_hash_sha256_BYTES];
|
||||||
|
crypto_hash_sha256(hash, key, key_length);
|
||||||
|
random_nonce(data);
|
||||||
|
encrypt_data_symmetric(hash, data, plain_messenger, m_size, data + crypto_secretbox_NONCEBYTES);
|
||||||
|
|
||||||
|
memset(plain_messenger, 0, m_size);
|
||||||
|
free(plain_messenger);
|
||||||
|
memset(hash, 0, crypto_hash_sha256_BYTES);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the messenger from data of size length encrypted with key of key_length.
|
||||||
|
*
|
||||||
|
* return 0 on success.
|
||||||
|
* return -1 on failure.
|
||||||
|
*/
|
||||||
|
int messenger_load_encrypted(Messenger *m, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length)
|
||||||
|
{
|
||||||
|
if (length <= crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint8_t *plain_messenger = malloc(length);
|
||||||
|
|
||||||
|
if (plain_messenger == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Hash the key with SHA256 to get a 32byte key. */
|
||||||
|
uint8_t hash[crypto_hash_sha256_BYTES];
|
||||||
|
crypto_hash_sha256(hash, key, key_length);
|
||||||
|
int len = decrypt_data_symmetric(hash, data, data + crypto_secretbox_NONCEBYTES, length - crypto_secretbox_NONCEBYTES,
|
||||||
|
plain_messenger);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ((uint32_t)len == length - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES) {
|
||||||
|
ret = messenger_load(m, plain_messenger, length - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES);
|
||||||
|
} else {
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(plain_messenger, 0, length);
|
||||||
|
free(plain_messenger);
|
||||||
|
memset(hash, 0, crypto_hash_sha256_BYTES);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the number of friends in the instance m.
|
/* Return the number of friends in the instance m.
|
||||||
* You should use this to determine how much memory to allocate
|
* You should use this to determine how much memory to allocate
|
||||||
* for copy_friendlist. */
|
* for copy_friendlist. */
|
||||||
|
@ -652,6 +652,24 @@ void messenger_save(Messenger *m, uint8_t *data);
|
|||||||
/* Load the messenger from data of size length. */
|
/* Load the messenger from data of size length. */
|
||||||
int messenger_load(Messenger *m, uint8_t *data, uint32_t length);
|
int messenger_load(Messenger *m, uint8_t *data, uint32_t length);
|
||||||
|
|
||||||
|
/* return the size of data to pass to messenger_save_encrypted(...)
|
||||||
|
*/
|
||||||
|
uint32_t messenger_size_encrypted(Messenger *m);
|
||||||
|
|
||||||
|
/* Save the messenger, encrypting the data with key of length key_length
|
||||||
|
*
|
||||||
|
* return 0 on success.
|
||||||
|
* return -1 on failure.
|
||||||
|
*/
|
||||||
|
int messenger_save_encrypted(Messenger *m, uint8_t *data, uint8_t *key, uint16_t key_length);
|
||||||
|
|
||||||
|
/* Load the messenger from data of size length encrypted with key of key_length.
|
||||||
|
*
|
||||||
|
* return 0 on success.
|
||||||
|
* return -1 on failure.
|
||||||
|
*/
|
||||||
|
int messenger_load_encrypted(Messenger *m, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length);
|
||||||
|
|
||||||
/* Return the number of friends in the instance m.
|
/* Return the number of friends in the instance m.
|
||||||
* You should use this to determine how much memory to allocate
|
* You should use this to determine how much memory to allocate
|
||||||
* for copy_friendlist. */
|
* for copy_friendlist. */
|
||||||
|
@ -82,6 +82,7 @@ typedef int sock_t;
|
|||||||
#include <crypto_box.h>
|
#include <crypto_box.h>
|
||||||
#include <crypto_secretbox.h>
|
#include <crypto_secretbox.h>
|
||||||
#include <randombytes.h>
|
#include <randombytes.h>
|
||||||
|
#include <crypto_hash_sha256.h>
|
||||||
#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
|
#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -749,3 +749,32 @@ int tox_load(Tox *tox, uint8_t *data, uint32_t length)
|
|||||||
return messenger_load(m, data, length);
|
return messenger_load(m, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return the size of data to pass to messenger_save_encrypted(...)
|
||||||
|
*/
|
||||||
|
uint32_t tox_size_encrypted(Tox *tox)
|
||||||
|
{
|
||||||
|
Messenger *m = tox;
|
||||||
|
return messenger_size_encrypted(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the messenger, encrypting the data with key of length key_length
|
||||||
|
*
|
||||||
|
* return 0 on success.
|
||||||
|
* return -1 on failure.
|
||||||
|
*/
|
||||||
|
int tox_save_encrypted(Tox *tox, uint8_t *data, uint8_t *key, uint16_t key_length)
|
||||||
|
{
|
||||||
|
Messenger *m = tox;
|
||||||
|
return messenger_save_encrypted(m, data, key, key_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the messenger from data of size length encrypted with key of key_length.
|
||||||
|
*
|
||||||
|
* return 0 on success.
|
||||||
|
* return -1 on failure.
|
||||||
|
*/
|
||||||
|
int tox_load_encrypted(Tox *tox, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length)
|
||||||
|
{
|
||||||
|
Messenger *m = tox;
|
||||||
|
return messenger_load_encrypted(m, data, length, key, key_length);
|
||||||
|
}
|
||||||
|
@ -657,9 +657,38 @@ uint32_t tox_size(Tox *tox);
|
|||||||
/* Save the messenger in data (must be allocated memory of size Messenger_size()). */
|
/* Save the messenger in data (must be allocated memory of size Messenger_size()). */
|
||||||
void tox_save(Tox *tox, uint8_t *data);
|
void tox_save(Tox *tox, uint8_t *data);
|
||||||
|
|
||||||
/* Load the messenger from data of size length. */
|
/* Load the messenger from data of size length.
|
||||||
|
*
|
||||||
|
* returns 0 on success
|
||||||
|
* returns -1 on failure
|
||||||
|
*/
|
||||||
int tox_load(Tox *tox, uint8_t *data, uint32_t length);
|
int tox_load(Tox *tox, uint8_t *data, uint32_t length);
|
||||||
|
|
||||||
|
/**/
|
||||||
|
|
||||||
|
/* return the size of data to pass to messenger_save_encrypted(...)
|
||||||
|
*/
|
||||||
|
uint32_t tox_size_encrypted(Tox *tox);
|
||||||
|
|
||||||
|
/* Save the messenger, encrypting the data with key of length key_length
|
||||||
|
*
|
||||||
|
* This functions simply calls and then encrypt the output of tox_save(..)
|
||||||
|
* with crypto_secretbox(...) from NaCl/libsodium with the key
|
||||||
|
* given to crypto_secretbox(...) being the SHA256 sum of the key
|
||||||
|
* passed to this function.
|
||||||
|
*
|
||||||
|
* return 0 on success.
|
||||||
|
* return -1 on failure.
|
||||||
|
*/
|
||||||
|
int tox_save_encrypted(Tox *tox, uint8_t *data, uint8_t *key, uint16_t key_length);
|
||||||
|
|
||||||
|
/* Load the messenger from data of size length encrypted with key of key_length.
|
||||||
|
*
|
||||||
|
* return 0 on success.
|
||||||
|
* return -1 on failure.
|
||||||
|
*/
|
||||||
|
int tox_load_encrypted(Tox *tox, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user