diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 07504988..3308b1ed 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -186,6 +186,10 @@ int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t leng uint8_t client_id[crypto_box_PUBLICKEYBYTES]; id_copy(client_id, address); + + if (!public_key_valid(client_id)) + return FAERR_BADCHECKSUM; + uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check)); @@ -261,6 +265,9 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id) if (getfriend_id(m, client_id) != -1) return -1; + if (!public_key_valid(client_id)) + return -1; + /* Resize the friend list if necessary. */ if (realloc_friendlist(m, m->numfriends + 1) != 0) return FAERR_NOMEM; diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 87e276e7..1799b600 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -66,6 +66,20 @@ uint64_t random_64b(void) return randnum; } +/* Check if a Tox public key crypto_box_PUBLICKEYBYTES is valid or not. + * This should only be used for input validation. + * + * return 0 if it isn't. + * return 1 if it is. + */ +int public_key_valid(const uint8_t *public_key) +{ + if (public_key[31] >= 128) /* Last bit of key is always zero. */ + return 0; + + return 1; +} + /* Precomputes the shared key from their public_key and our secret_key. * This way we can avoid an expensive elliptic curve scalar multiply for each * encrypt/decrypt operation. diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 814c4362..7362d49e 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -53,6 +53,13 @@ int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, uint32_t length); uint32_t random_int(void); uint64_t random_64b(void); +/* Check if a Tox public key crypto_box_PUBLICKEYBYTES is valid or not. + * This should only be used for input validation. + * + * return 0 if it isn't. + * return 1 if it is. + */ +int public_key_valid(const uint8_t *public_key); /* Encrypts plain of length length to encrypted of length + 16 using the * public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce.