1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-25 13:03:02 +01:00

Add some simple impersonation detection on friend requests

This will alert the user when the first six bytes of a new
contact's public key is the same as any other contact in
their list. These 6 bytes are used elsewhere in toxic for
unique identification.

Also did a small refactor regarding the KEY_IDENT_BYTES
define
This commit is contained in:
jfreegman 2022-01-23 11:32:57 -05:00
parent 05dbc626e2
commit f6f41a510b
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
4 changed files with 37 additions and 12 deletions

View File

@ -1385,7 +1385,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
self->x = x2; self->x = x2;
/* Truncate note if it doesn't fit in statusbar */ /* Truncate note if it doesn't fit in statusbar */
size_t maxlen = x2 - getcurx(statusbar->topline) - (KEY_IDENT_DIGITS * 2) - 6; size_t maxlen = x2 - getcurx(statusbar->topline) - KEY_IDENT_BYTES - 6;
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
size_t statusmsg_len = statusbar->statusmsg_len; size_t statusmsg_len = statusbar->statusmsg_len;
@ -1416,10 +1416,10 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
int s_x; int s_x;
getyx(statusbar->topline, s_y, s_x); getyx(statusbar->topline, s_y, s_x);
mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - (KEY_IDENT_DIGITS * 2) - 3); mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - KEY_IDENT_BYTES - 3);
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT)); wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wmove(statusbar->topline, 0, x2 - (KEY_IDENT_DIGITS * 2) - 3); wmove(statusbar->topline, 0, x2 - KEY_IDENT_BYTES - 3);
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "{"); wprintw(statusbar->topline, "{");
@ -1427,7 +1427,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT)); wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
for (size_t i = 0; i < KEY_IDENT_DIGITS; ++i) { for (size_t i = 0; i < KEY_IDENT_BYTES / 2; ++i) {
wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff); wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff);
} }

View File

@ -62,21 +62,21 @@ static int get_log_path(char *dest, int destsize, const char *name, const char *
/* first 6 bytes of selfkey */ /* first 6 bytes of selfkey */
char self_id[32] = {0}; char self_id[32] = {0};
path_len += KEY_IDENT_DIGITS * 2; path_len += KEY_IDENT_BYTES;
sprintf(&self_id[0], "%02X", selfkey[0] & 0xff); sprintf(&self_id[0], "%02X", selfkey[0] & 0xff);
sprintf(&self_id[2], "%02X", selfkey[1] & 0xff); sprintf(&self_id[2], "%02X", selfkey[1] & 0xff);
sprintf(&self_id[4], "%02X", selfkey[2] & 0xff); sprintf(&self_id[4], "%02X", selfkey[2] & 0xff);
self_id[KEY_IDENT_DIGITS * 2] = '\0'; self_id[KEY_IDENT_BYTES] = '\0';
char other_id[32] = {0}; char other_id[32] = {0};
if (otherkey) { if (otherkey) {
/* first 6 bytes of otherkey */ /* first 6 bytes of otherkey */
path_len += KEY_IDENT_DIGITS * 2; path_len += KEY_IDENT_BYTES;
sprintf(&other_id[0], "%02X", otherkey[0] & 0xff); sprintf(&other_id[0], "%02X", otherkey[0] & 0xff);
sprintf(&other_id[2], "%02X", otherkey[1] & 0xff); sprintf(&other_id[2], "%02X", otherkey[1] & 0xff);
sprintf(&other_id[4], "%02X", otherkey[2] & 0xff); sprintf(&other_id[4], "%02X", otherkey[2] & 0xff);
other_id[KEY_IDENT_DIGITS * 2] = '\0'; other_id[KEY_IDENT_BYTES] = '\0';
} }
if (path_len >= destsize) { if (path_len >= destsize) {

View File

@ -175,9 +175,7 @@ static int add_friend_request(const char *public_key, const char *data)
return -1; return -1;
} }
int i; for (int i = 0; i <= FrndRequests.max_idx; ++i) {
for (i = 0; i <= FrndRequests.max_idx; ++i) {
if (!FrndRequests.request[i].active) { if (!FrndRequests.request[i].active) {
FrndRequests.request[i].active = true; FrndRequests.request[i].active = true;
memcpy(FrndRequests.request[i].key, public_key, TOX_PUBLIC_KEY_SIZE); memcpy(FrndRequests.request[i].key, public_key, TOX_PUBLIC_KEY_SIZE);
@ -526,6 +524,26 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnu
} }
} }
/**
* Return true is the first 3 bytes of `key` are identical to any other contact in the contact list.
*/
static bool key_is_similar(const char *key)
{
for (size_t i = 0; i < Friends.max_idx; ++i) {
const ToxicFriend *friend = &Friends.list[i];
if (!friend->active) {
continue;
}
if (memcmp(friend->pub_key, key, KEY_IDENT_BYTES / 2) == 0) {
return true;
}
}
return false;
}
static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length) static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length)
{ {
UNUSED_VAR(m); UNUSED_VAR(m);
@ -536,6 +554,13 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, con
line_info_add(self, true, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data); line_info_add(self, true, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data);
write_to_log("Friend request with the message '%s'", "", ctx->log, true); write_to_log("Friend request with the message '%s'", "", ctx->log, true);
if (key_is_similar(key)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED,
"WARNING: This contact's public key is suspiciously similar to that of another contact ");
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED,
"in your list. This may be an impersonation attempt, or it may have occurred by chance.");
}
int n = add_friend_request(key, data); int n = add_friend_request(key, data);
if (n == -1) { if (n == -1) {

View File

@ -46,7 +46,7 @@
#define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH /* must be >= TOX_MAX_MESSAGE_LENGTH */ #define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH /* must be >= TOX_MAX_MESSAGE_LENGTH */
#define MAX_CMDNAME_SIZE 64 #define MAX_CMDNAME_SIZE 64
#define TOXIC_MAX_NAME_LENGTH 32 /* Must be <= TOX_MAX_NAME_LENGTH */ #define TOXIC_MAX_NAME_LENGTH 32 /* Must be <= TOX_MAX_NAME_LENGTH */
#define KEY_IDENT_DIGITS 3 /* number of hex digits to display for the pub-key based identifier */ #define KEY_IDENT_BYTES 6 /* number of hex digits to display for the public key identifier */
#define TIME_STR_SIZE 32 #define TIME_STR_SIZE 32
#define COLOR_STR_SIZE 10 /* should fit every color option */ #define COLOR_STR_SIZE 10 /* should fit every color option */