Added function to save an encrypted version of the messenger.

Also added some tests.
This commit is contained in:
irungentoo 2013-12-21 22:35:27 -05:00
parent 83cb946db0
commit c51b8a9eba
7 changed files with 200 additions and 1 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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. */

View File

@ -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. */

View File

@ -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

View File

@ -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);
}

View File

@ -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
}