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
|
||||
|
||||
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) \
|
||||
TCase *NAME = tcase_create(#NAME); \
|
||||
tcase_add_test(NAME, test_##NAME); \
|
||||
|
@ -263,6 +293,7 @@ Suite *crypto_suite(void)
|
|||
DEFTESTCASE(fast_known);
|
||||
DEFTESTCASE_SLOW(endtoend, 15); /* waiting up to 15 seconds */
|
||||
DEFTESTCASE(large_data);
|
||||
DEFTESTCASE(large_data_symmetric);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -310,6 +310,27 @@ START_TEST(test_messenger_state_saveloadsave)
|
|||
}
|
||||
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) \
|
||||
TCase *tc_##NAME = tcase_create(#NAME); \
|
||||
tcase_add_test(tc_##NAME, test_##NAME); \
|
||||
|
@ -321,6 +342,7 @@ Suite *messenger_suite(void)
|
|||
|
||||
DEFTESTCASE(dht_state_saveloadsave);
|
||||
DEFTESTCASE(messenger_state_saveloadsave);
|
||||
DEFTESTCASE(messenger_state_saveload_encrypted);
|
||||
|
||||
DEFTESTCASE(getself_name);
|
||||
DEFTESTCASE(m_get_userstatus_size);
|
||||
|
|
|
@ -2264,6 +2264,75 @@ int messenger_load(Messenger *m, uint8_t *data, uint32_t length)
|
|||
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.
|
||||
* You should use this to determine how much memory to allocate
|
||||
* for copy_friendlist. */
|
||||
|
|
|
@ -652,6 +652,24 @@ void messenger_save(Messenger *m, uint8_t *data);
|
|||
/* Load the messenger from data of size 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.
|
||||
* You should use this to determine how much memory to allocate
|
||||
* for copy_friendlist. */
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef int sock_t;
|
|||
#include <crypto_box.h>
|
||||
#include <crypto_secretbox.h>
|
||||
#include <randombytes.h>
|
||||
#include <crypto_hash_sha256.h>
|
||||
#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -749,3 +749,32 @@ int tox_load(Tox *tox, uint8_t *data, uint32_t 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()). */
|
||||
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);
|
||||
|
||||
/**/
|
||||
|
||||
/* 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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user