diff --git a/testing/test_avatars.c b/testing/test_avatars.c index 7d96bd52..fc7e9d6f 100644 --- a/testing/test_avatars.c +++ b/testing/test_avatars.c @@ -86,8 +86,8 @@ typedef struct { static const def_avatar_name_t def_avatar_names[] = { /* In order of preference */ - { TOX_AVATARFORMAT_PNG, "png", "avatar.png" }, - { TOX_AVATARFORMAT_NONE, NULL, NULL }, /* Must be the last one */ + { TOX_AVATAR_FORMAT_PNG, "png", "avatar.png" }, + { TOX_AVATAR_FORMAT_NONE, NULL, NULL }, /* Must be the last one */ }; @@ -99,7 +99,7 @@ static char *get_avatar_suffix_from_format(uint8_t format) { int i; - for (i = 0; def_avatar_names[i].format != TOX_AVATARFORMAT_NONE; i++) + for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) if (def_avatar_names[i].format == format) return def_avatar_names[i].suffix; @@ -118,7 +118,7 @@ static int load_avatar_data(char *fname, uint8_t *buf) if (fp == NULL) return -1; /* Error */ - size_t n = fread(buf, 1, TOX_MAX_AVATAR_DATA_LENGTH, fp); + size_t n = fread(buf, 1, TOX_AVATAR_MAX_DATA_LENGTH, fp); int ret; if (ferror(fp) != 0 || n == 0) @@ -267,7 +267,7 @@ static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum) /* This iteration is dumb and inefficient */ int i; - for (i = 0; def_avatar_names[i].format != TOX_AVATARFORMAT_NONE; i++) { + for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) { int ret = make_avatar_file_name(path, sizeof(path), base_dir, def_avatar_names[i].format, addr); @@ -318,7 +318,7 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t * byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str); DEBUG("format=%u, hash=%s", format, hash_str); - if (format == TOX_AVATARFORMAT_NONE) { + if (format == TOX_AVATAR_FORMAT_NONE) { printf(" -> User do not have an avatar.\n"); /* User have no avatar anymore, delete it from our cache */ delete_user_avatar(tox, base_dir, n); @@ -332,7 +332,7 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t * * these events. */ uint32_t cur_av_len; - uint8_t cur_av_data[TOX_MAX_AVATAR_DATA_LENGTH]; + uint8_t cur_av_data[TOX_AVATAR_MAX_DATA_LENGTH]; uint8_t cur_av_hash[TOX_AVATAR_HASH_LENGTH]; int ret; @@ -370,7 +370,7 @@ static void friend_avatar_data_cb(Tox *tox, int32_t n, uint8_t format, delete_user_avatar(tox, base_dir, n); - if (format != TOX_AVATARFORMAT_NONE) { + if (format != TOX_AVATAR_FORMAT_NONE) { int ret = save_user_avatar(tox, base_dir, n, format, data, datalen); if (ret == 0) @@ -406,7 +406,7 @@ static void friend_msg_cb(Tox *tox, int n, const uint8_t *msg, uint16_t len, voi set_avatar(tox, base_dir); reply_ptr = "Setting image avatar"; } else if (strstr(msg_str, "!remove-avatar") != NULL) { - int r = tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0); + int r = tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0); DEBUG("tox_set_avatar returned %d", r); reply_ptr = "Removing avatar"; } @@ -453,10 +453,10 @@ static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name FILE *fp = fopen(path, "rb"); if (fp != NULL) { - uint8_t buf[2 * TOX_MAX_AVATAR_DATA_LENGTH]; + uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH]; int len = fread(buf, 1, sizeof(buf), fp); - if (len >= 0 && len <= TOX_MAX_AVATAR_DATA_LENGTH) { + if (len >= 0 && len <= TOX_AVATAR_MAX_DATA_LENGTH) { int r = tox_set_avatar(tox, an->format, buf, len); DEBUG("%d bytes, tox_set_avatar returned=%d", len, r); @@ -468,7 +468,7 @@ static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name DEBUG("read error %d", len); } else { printf("Avatar file %s if too big (more than %d bytes)", - path, TOX_MAX_AVATAR_DATA_LENGTH); + path, TOX_AVATAR_MAX_DATA_LENGTH); } fclose(fp); @@ -486,8 +486,8 @@ static void set_avatar(Tox *tox, const char *base_dir) int i; for (i = 0; i < 4; i++) { - if (def_avatar_names[i].format == TOX_AVATARFORMAT_NONE) { - tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0); + if (def_avatar_names[i].format == TOX_AVATAR_FORMAT_NONE) { + tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0); printf("No avatar file found, setting to NONE.\n"); return; } else { @@ -504,7 +504,7 @@ static void set_avatar(Tox *tox, const char *base_dir) static void print_avatar_info(Tox *tox) { uint8_t format; - uint8_t data[TOX_MAX_AVATAR_DATA_LENGTH]; + uint8_t data[TOX_AVATAR_MAX_DATA_LENGTH]; uint8_t hash[TOX_AVATAR_HASH_LENGTH]; uint32_t data_length; char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1]; diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 3d96f6ca..99b95f67 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -576,10 +576,10 @@ int m_set_userstatus(Messenger *m, uint8_t status) int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length) { - if (length > MAX_AVATAR_DATA_LENGTH) + if (length > AVATAR_MAX_DATA_LENGTH) return -1; - if (format == AVATARFORMAT_NONE) { + if (format == AVATAR_FORMAT_NONE) { free(m->avatar_data); m->avatar_data = NULL; m->avatar_data_length = 0; @@ -632,15 +632,18 @@ int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_ return 0; } -int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen) +int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen) { if (hash == NULL) return -1; - crypto_hash_sha256(hash, data, datalen); - return 0; + return crypto_hash_sha256(hash, data, datalen); } +int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen) +{ + return m_hash(hash, data, datalen); +} int m_request_avatar_info(const Messenger *m, const int32_t friendnumber) { @@ -673,10 +676,10 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber) if (friend_not_valid(m, friendnumber)) return -1; - AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; + AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; if (avrd == NULL) { - avrd = calloc(sizeof(AVATARRECEIVEDATA), 1); + avrd = calloc(sizeof(AVATAR_RECEIVEDATA), 1); if (avrd == NULL) return -1; @@ -693,9 +696,9 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber) avrd->started = 0; avrd->bytes_received = 0; avrd->total_length = 0; - avrd->format = AVATARFORMAT_NONE; + avrd->format = AVATAR_FORMAT_NONE; - return send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_REQ); + return send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_REQ); } @@ -2006,7 +2009,7 @@ Messenger *new_messenger(Messenger_Options *options) m->net = new_networking(ip, TOX_PORT_DEFAULT); } - m->avatar_format = AVATARFORMAT_NONE; + m->avatar_format = AVATAR_FORMAT_NONE; m->avatar_data = NULL; if (m->net == NULL) { @@ -2159,17 +2162,17 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber, LOGGER_DEBUG("Error: PACKET_ID_AVATAR_DATA_CONTROL with bad " "data_length = %u, friendnumber = %u", data_length, friendnumber); - send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); + send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR); return -1; /* Error */ } LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]); switch (data[0]) { - case AVATARDATACONTROL_REQ: { + case AVATAR_DATACONTROL_REQ: { /* Check data transfer limits for this friend */ - AVATARSENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data); + AVATAR_SENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data); if (avsd->bytes_sent >= AVATAR_DATA_TRANSFER_LIMIT) { /* User reached data limit. Check timeout */ @@ -2183,7 +2186,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber, /* Friend still rate-limitted. Send an error and stops. */ LOGGER_DEBUG("Avatar data transfer limit reached. " "friendnumber = %u", friendnumber); - send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); + send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR); return 0; } } @@ -2211,12 +2214,12 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber, if (!ret) { /* Something went wrong, try to signal the error so the friend * can clear up the state. */ - send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); + send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR); return 0; } /* User have no avatar data, nothing more to do. */ - if (m->avatar_format == AVATARFORMAT_NONE) + if (m->avatar_format == AVATAR_FORMAT_NONE) return 0; /* Send the actual avatar data. */ @@ -2241,7 +2244,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber, LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, " "friendnumber = %u, offset = %u", ret, friendnumber, offset); - send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); + send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR); return -1; } } @@ -2249,7 +2252,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber, return 0; } - case AVATARDATACONTROL_ERROR: { + case AVATAR_DATACONTROL_ERROR: { if (m->friendlist[friendnumber].avatar_recv_data) { /* We were receiving the data, sender detected an error (eg. changing avatar) and asked us to stop. */ @@ -2276,7 +2279,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber, return -1; } - AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; + AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; if (avrd == NULL) { LOGGER_DEBUG("Received an unrequested DATA_START, friendnumber = %u", @@ -2307,7 +2310,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber, friendnumber, avrd->format, avrd->total_length, avrd->bytes_received); - if (avrd->total_length > MAX_AVATAR_DATA_LENGTH) { + if (avrd->total_length > AVATAR_MAX_DATA_LENGTH) { /* Invalid data length. Stops. */ LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, " "friendnumber = %u", friendnumber); @@ -2317,7 +2320,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber, return 0; } - if (avrd->format == AVATARFORMAT_NONE || avrd->total_length == 0) { + if (avrd->format == AVATAR_FORMAT_NONE || avrd->total_length == 0) { /* No real data to receive. Run callback function and finish. */ LOGGER_DEBUG("format == NONE, friendnumber = %u", friendnumber); @@ -2343,7 +2346,7 @@ static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber, { LOGGER_DEBUG("friendnumber = %u, data_length = %u", friendnumber, data_length); - AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; + AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; if (avrd == NULL) { /* No active transfer. It must be an error or a malicious request, @@ -2363,7 +2366,7 @@ static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber, uint32_t new_length = avrd->bytes_received + data_length; if (new_length > avrd->total_length - || new_length >= MAX_AVATAR_DATA_LENGTH) { + || new_length >= AVATAR_MAX_DATA_LENGTH) { /* Invalid data length due to error or malice. Stops. */ LOGGER_DEBUG("Invalid data length. friendnumber = %u, " "new_length = %u, avrd->total_length = %u", diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index a107d80f..e6877002 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -36,8 +36,8 @@ #define MAX_NAME_LENGTH 128 /* TODO: this must depend on other variable. */ #define MAX_STATUSMESSAGE_LENGTH 1007 -#define MAX_AVATAR_DATA_LENGTH 16384 -#define AVATAR_HASH_LENGTH 32 +#define AVATAR_MAX_DATA_LENGTH 16384 +#define AVATAR_HASH_LENGTH crypto_hash_sha256_BYTES #define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t)) @@ -121,7 +121,7 @@ enum { #define AVATAR_DATA_MAX_CHUNK_SIZE (MAX_CRYPTO_DATA_SIZE-1) /* Per-friend data limit for avatar data requests */ -#define AVATAR_DATA_TRANSFER_LIMIT (10*MAX_AVATAR_DATA_LENGTH) +#define AVATAR_DATA_TRANSFER_LIMIT (10*AVATAR_MAX_DATA_LENGTH) #define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */ @@ -137,40 +137,40 @@ typedef enum { } USERSTATUS; -/* AVATARFORMAT - +/* AVATAR_FORMAT - * Data formats for user avatar images */ typedef enum { - AVATARFORMAT_NONE, - AVATARFORMAT_PNG + AVATAR_FORMAT_NONE = 0, + AVATAR_FORMAT_PNG } -AVATARFORMAT; +AVATAR_FORMAT; -/* AVATARDATACONTROL +/* AVATAR_DATACONTROL * To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL) */ typedef enum { - AVATARDATACONTROL_REQ, - AVATARDATACONTROL_ERROR + AVATAR_DATACONTROL_REQ, + AVATAR_DATACONTROL_ERROR } -AVATARDATACONTROL; +AVATAR_DATACONTROL; typedef struct { uint8_t started; - AVATARFORMAT format; + AVATAR_FORMAT format; uint8_t hash[AVATAR_HASH_LENGTH]; uint32_t total_length; uint32_t bytes_received; - uint8_t data[MAX_AVATAR_DATA_LENGTH]; + uint8_t data[AVATAR_MAX_DATA_LENGTH]; } -AVATARRECEIVEDATA; +AVATAR_RECEIVEDATA; typedef struct { /* Fields only used to limit the network usage from a given friend */ uint32_t bytes_sent; /* Total bytes send to this user */ uint64_t last_reset; /* Time the data counter was last reset */ } -AVATARSENDDATA; +AVATAR_SENDDATA; struct File_Transfers { @@ -230,8 +230,8 @@ typedef struct { int invited_groups[MAX_INVITED_GROUPS]; uint16_t invited_groups_num; - AVATARSENDDATA avatar_send_data; - AVATARRECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend. + AVATAR_SENDDATA avatar_send_data; + AVATAR_RECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend. struct { int (*function)(void *object, const uint8_t *data, uint32_t len); @@ -264,7 +264,7 @@ typedef struct Messenger { USERSTATUS userstatus; - AVATARFORMAT avatar_format; + AVATAR_FORMAT avatar_format; uint8_t *avatar_data; uint32_t avatar_data_length; uint8_t avatar_hash[AVATAR_HASH_LENGTH]; @@ -509,7 +509,7 @@ uint8_t m_get_self_userstatus(const Messenger *m); * Notice that the library treats the image as raw data and does not interpret it by any way. * * Arguments: - * format - Avatar image format or NONE for user with no avatar (see AVATARFORMAT); + * format - Avatar image format or NONE for user with no avatar (see AVATAR_FORMAT); * data - pointer to the avatar data (may be NULL it the format is NONE); * length - length of image data. Must be <= MAX_AVATAR_DATA_LENGTH. * @@ -528,7 +528,7 @@ int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t len * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored. * * Arguments: - * format - destination pointer to the avatar image format (see AVATARFORMAT); + * format - destination pointer to the avatar image format (see AVATAR_FORMAT); * buf - destination buffer to the image data. Must have at least 'maxlen' bytes; * length - destination pointer to the image data length; * maxlen - length of the destination buffer 'buf'; @@ -541,8 +541,23 @@ int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t len int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash); +/* Generates a cryptographic hash of the given data. + * This function may be used by clients for any purpose, but is provided primarily for + * validating cached avatars. + * This function is a wrapper to internal message-digest functions. + * + * Arguments: + * hash - destination buffer for the hash data, it must be exactly crypto_hash_sha256_BYTES bytes long. + * data - data to be hashed; + * datalen - length of the data; + * + * returns 0 on success + * returns -1 on failure. + */ +int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); + /* Generates a cryptographic hash of the given avatar data. - * This function is a wrapper to internal message-digest functions and specifically provided + * This function is a wrapper to m_hash and specifically provided * to generate hashes from user avatars that may be memcmp()ed with the values returned by the * other avatar functions. It is specially important to validate cached avatars. * @@ -694,7 +709,7 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess * Function format is: * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata) * - * where 'format' is the avatar image format (see AVATARFORMAT) and 'hash' is the hash of + * where 'format' is the avatar image format (see AVATAR_FORMAT) and 'hash' is the hash of * the avatar data for caching purposes and it is exactly AVATAR_HASH_LENGTH long. If the * image format is NONE, the hash is zeroed. * @@ -710,7 +725,7 @@ void m_callback_avatar_info(Messenger *m, void (*function)(Messenger *m, int32_t * Function format is: * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata) * - * where 'format' is the avatar image format (see AVATARFORMAT); 'hash' is the + * where 'format' is the avatar image format (see AVATAR_FORMAT); 'hash' is the * locally-calculated cryptographic hash of the avatar data and it is exactly * AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length * of such data. diff --git a/toxcore/tox.c b/toxcore/tox.c index b44f0ee6..819a67dd 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -826,9 +826,14 @@ int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t return m_get_self_avatar(m, format, buf, length, maxlen, hash); } +int tox_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen) +{ + return m_hash(hash, data, datalen); +} + int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen) { - return m_avatar_hash(hash, data, datalen); + return m_hash(hash, data, datalen); } int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber) diff --git a/toxcore/tox.h b/toxcore/tox.h index a5efee34..c5484fba 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -37,8 +37,9 @@ extern "C" { #define TOX_MAX_MESSAGE_LENGTH 1368 #define TOX_MAX_STATUSMESSAGE_LENGTH 1007 #define TOX_CLIENT_ID_SIZE 32 -#define TOX_MAX_AVATAR_DATA_LENGTH 16384 -#define TOX_AVATAR_HASH_LENGTH 32 +#define TOX_AVATAR_MAX_DATA_LENGTH 16384 +#define TOX_AVATAR_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32 +#define TOX_HASH_LENGTH TOX_AVATAR_HASH_LENGTH #define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) @@ -73,14 +74,14 @@ typedef enum { TOX_USERSTATUS; -/* AVATARFORMAT - +/* AVATAR_FORMAT - * Data formats for user avatar images */ typedef enum { - TOX_AVATARFORMAT_NONE, - TOX_AVATARFORMAT_PNG + TOX_AVATAR_FORMAT_NONE = 0, + TOX_AVATAR_FORMAT_PNG } -TOX_AVATARFORMAT; +TOX_AVATAR_FORMAT; #ifndef __TOX_DEFINED__ #define __TOX_DEFINED__ @@ -538,7 +539,7 @@ uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size); * Function format is: * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata) * - * where 'format' is the avatar image format (see TOX_AVATARFORMAT) and 'hash' is the hash of + * where 'format' is the avatar image format (see TOX_AVATAR_FORMAT) and 'hash' is the hash of * the avatar data for caching purposes and it is exactly TOX_AVATAR_HASH_LENGTH long. If the * image format is NONE, the hash is zeroed. * @@ -554,7 +555,7 @@ void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint * Function format is: * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata) * - * where 'format' is the avatar image format (see TOX_AVATARFORMAT); 'hash' is the + * where 'format' is the avatar image format (see TOX_AVATAR_FORMAT); 'hash' is the * locally-calculated cryptographic hash of the avatar data and it is exactly * TOX_AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length * of such data. @@ -577,9 +578,9 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint * Notice that the library treats the image as raw data and does not interpret it by any way. * * Arguments: - * format - Avatar image format or NONE for user with no avatar (see TOX_AVATARFORMAT); + * format - Avatar image format or NONE for user with no avatar (see TOX_AVATAR_FORMAT); * data - pointer to the avatar data (may be NULL it the format is NONE); - * length - length of image data. Must be <= TOX_MAX_AVATAR_DATA_LENGTH. + * length - length of image data. Must be <= TOX_AVATAR_MAX_DATA_LENGTH. * * returns 0 on success * returns -1 on failure. @@ -597,7 +598,7 @@ int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t lengt * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored. * * Arguments: - * format - destination pointer to the avatar image format (see TOX_AVATARFORMAT); + * format - destination pointer to the avatar image format (see TOX_AVATAR_FORMAT); * buf - destination buffer to the image data. Must have at least 'maxlen' bytes; * length - destination pointer to the image data length; * maxlen - length of the destination buffer 'buf'; @@ -611,15 +612,30 @@ int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t uint8_t *hash); +/* Generates a cryptographic hash of the given data. + * This function may be used by clients for any purpose, but is provided primarily for + * validating cached avatars. + * This function is a wrapper to internal message-digest functions. + * + * Arguments: + * hash - destination buffer for the hash data, it must be exactly TOX_HASH_LENGTH bytes long. + * data - data to be hashed; + * datalen - length of the data; + * + * returns 0 on success + * returns -1 on failure. + */ +int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); + /* Generates a cryptographic hash of the given avatar data. - * This function is a wrapper to internal message-digest functions and specifically provided + * This function is a wrapper to tox_hash and specifically provided * to generate hashes from user avatars that may be memcmp()ed with the values returned by the * other avatar functions. It is specially important to validate cached avatars. * * Arguments: * hash - destination buffer for the hash data, it must be exactly TOX_AVATAR_HASH_LENGTH bytes long. * data - avatar image data; - * datalen - length of the avatar image data; it must be <= TOX_MAX_AVATAR_DATA_LENGTH. + * datalen - length of the avatar image data; it must be <= MAX_AVATAR_DATA_LENGTH. * * returns 0 on success * returns -1 on failure.