spelling, punctuation, ...

This commit is contained in:
aaannndddyyy 2015-03-05 10:54:42 +00:00
parent 1e17b468e6
commit c955728ac7

View File

@ -12,7 +12,7 @@ This document describes the implementation of avatars in the Tox protocol,
according to the following design considerations: according to the following design considerations:
- Avatars are handled as private information, i.e., they are only exchanged - Avatars are handled as private information, i.e., they are only exchanged
over Tox encrypted channels among previously authenticated friends; over Tox encrypted channels among previously authenticated friends.
- The library treats all images as blobs and does not interpret or - The library treats all images as blobs and does not interpret or
understand image formats. It only ensures that the avatar data sent by understand image formats. It only ensures that the avatar data sent by
@ -33,7 +33,7 @@ according to the following design considerations:
- The protocol MUST provide means to allow caching and avoid unnecessary - The protocol MUST provide means to allow caching and avoid unnecessary
data transfers. data transfers.
- Avatars are transfered between clients in a background operation. - Avatars are transferred between clients in a background operation.
- Avatars are served on a "best effort" basis, without breaking clients - Avatars are served on a "best effort" basis, without breaking clients
which do not support them. which do not support them.
@ -76,7 +76,7 @@ protocol. Moving this feature to the core protocol also:
This is a very high level description. The usage patterns expected from This is a very high level description. The usage patterns expected from
client applications are described in the section "Using Avatars in Client client applications are described in the section "Using Avatars in Client
Applications", and a low level protocol description is available in the Applications", and a low level protocol description is available in the
section "Internal Protocol Description".) section "Internal Protocol Description").
The avatar exchange is implemented with the following new elements in the The avatar exchange is implemented with the following new elements in the
Tox protocol: Tox protocol:
@ -84,7 +84,7 @@ Tox protocol:
a user to another anytime, but are usually sent after one of them a user to another anytime, but are usually sent after one of them
connects to the network, changes his avatar, or in reply to an **avatar connects to the network, changes his avatar, or in reply to an **avatar
information request**. They are delivered by a very lightweight message information request**. They are delivered by a very lightweight message
but with information enough to allow a user to validate or discard an but with enough information to allow a user to validate or discard an
avatar from the local cache and to decide if it is interesting to request avatar from the local cache and to decide if it is interesting to request
the avatar data from the peer. the avatar data from the peer.
@ -115,7 +115,7 @@ Tox protocol:
This event contains three data fields: (1) the image format, (2) the This event contains three data fields: (1) the image format, (2) the
cryptographic hash of the image data, and (3) the raw image data. If the cryptographic hash of the image data, and (3) the raw image data. If the
image format is NONE (i.e. no avatar) the hash is zeroed and the image image format is NONE (i.e. no avatar), the hash is zeroed and the image
data is empty. The raw image data is locally validated and ensured to data is empty. The raw image data is locally validated and ensured to
match the hash (the event is **not** triggered otherwise). match the hash (the event is **not** triggered otherwise).
@ -146,13 +146,13 @@ TOX_AVATAR_FORMAT;
/* Set the user avatar image data. */ /* Set the user avatar image data. */
int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length); int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length);
/* Removes the user avatar image data. */ /* Remove the user avatar image data. */
int tox_unset_avatar(Tox *tox); int tox_unset_avatar(Tox *tox);
/* Get avatar data from the current user. */ /* Get avatar data from the current user. */
int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash); int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash);
/* Generates a cryptographic hash of the given data (usually a cached avatar). */ /* Generate a cryptographic hash of the given data (usually a cached avatar). */
int tox_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); int tox_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen);
/* Request avatar information from a friend. */ /* Request avatar information from a friend. */
@ -181,17 +181,17 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint
- Clients MUST NOT imply the availability of avatars in other users. - Clients MUST NOT imply the availability of avatars in other users.
Avatars are an optional feature and not all users and clients may Avatars are an optional feature and not all users and clients may
support them; support them.
- Clients MUST NOT block waiting for avatar information and avatar data - Clients MUST NOT block waiting for avatar information and avatar data
packets; packets.
- Clients MUST treat avatar data as insecure and potentially malicious; - Clients MUST treat avatar data as insecure and potentially malicious.
For example, users may accidentally use corrupted images as avatars, For example, users may accidentally use corrupted images as avatars,
a malicious user may send a specially crafted image to exploit a know a malicious user may send a specially crafted image to exploit a known
vulnerability in an image decoding library, etc. It is recommended to vulnerability in an image decoding library, etc. It is recommended to
handle the avatar image data in the same way as an image downloaded handle the avatar image data in the same way as an image downloaded
from an unknown Internet source; from an unknown Internet source.
- The peers MUST NOT assume any coupling between the operations of - The peers MUST NOT assume any coupling between the operations of
receiving an avatar information packet, sending unrequested avatar receiving an avatar information packet, sending unrequested avatar
@ -200,36 +200,36 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint
For example, the following situations are valid: For example, the following situations are valid:
* A text-mode client may send avatars to other users, but never * A text-mode client may send avatars to other users, but never
request them; request them.
* A client may not understand a particular image format and ignore * A client may not understand a particular image format and ignore
avatars using it, but request and handle other formats; avatars using it, but request and handle other formats.
* A client on a slow mobile network may ask for avatar information to * A client on a slow mobile network may ask for avatar information to
ensure its cached avatars are still valid, but do not request avatar ensure its cached avatars are still valid, but not request avatar
data. The same client may start asking for avatar data once it data. The same client may start asking for avatar data once it
connects through a fast network. connects through a fast network.
- Clients SHOULD implement a local cache of avatars and do not request - Clients SHOULD implement a local cache of avatars and not request
avatar data from other peers unless necessary; avatar data from other peers unless necessary.
- When an avatar information is received, the client should delete the - When avatar information is received, the client should delete the
avatar if the new avatar format is NONE or compare the hash received avatar if the new avatar format is NONE or compare the hash received
from the peer with the hash of the currently cached avatar. If they from the peer with the hash of the currently cached avatar. If they
differ, send an avatar data request; differ, send an avatar data request.
- If the cached avatar is older than a given threshold, the client may - If the cached avatar is older than a given threshold, the client may
also send an avatar info request to that friend once he is online and also send an avatar info request to that friend once he is online and
mark the avatar as updated *before* any avatar information is received mark the avatar as updated *before* any avatar information is received
(to not spam the peer with such requests); (to not spam the peer with such requests).
- When an avatar data notification is received, the client must update - When an avatar data notification is received, the client must update
the cached avatar with the new one; the cached avatar with the new one.
- Clients should resize or crop the image to the way it better adapts - Clients should resize or crop the image such that it better adapts
to the client user interface; to the client's user interface.
- If the user already have an avatar defined in the client configuration, - If the user already has an avatar defined in the client configuration,
it must be set before connecting to the network to avoid spurious avatar it must be set before connecting to the network to avoid spurious avatar
change notifications and unnecessary data transfers. change notifications and unnecessary data transfers.
@ -241,10 +241,10 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint
### Interoperability and sharing avatars among different clients ### Interoperability and sharing avatars among different clients
**This section is a tentative recommendation of how clients should store **This section is a tentative recommendation of how clients should store
avatars to ensure local interoperability and should be revised if this avatars to ensure local interoperability, and should be revised if this
code is accepted into Tox core.** code is accepted into Tox core.**
It is desirable that the user avatar and the cached friends avatars could be It is desirable that the user avatar and the cached friends' avatars could be
shared among different Tox clients in the same system, in the spirit of the shared among different Tox clients in the same system, in the spirit of the
proposed Single Tox Standard. This not only makes switching from one client proposed Single Tox Standard. This not only makes switching from one client
to another easier, but also minimizes the need of data transfers, as avatars to another easier, but also minimizes the need of data transfers, as avatars
@ -262,10 +262,10 @@ Given the Tox data directory described in STS Draft v0.1.0:
- The client's own avatar is not special and is stored like any other. This - The client's own avatar is not special and is stored like any other. This
is partially for simplicity, and partially in anticipation of profiles. is partially for simplicity, and partially in anticipation of profiles.
- The avatar should be stored as its received, before any modifications by - The avatar should be stored as it was received, before any modifications by
the client for display purposes. the client for display purposes.
- The hash, as calculated by toxcore and passed in to the data callback, - The hash, as calculated by toxcore and passed into the data callback,
should be saved in "avatars/xxxxx.hash" where "xxxxx" means the should be saved in "avatars/xxxxx.hash" where "xxxxx" means the
same thing as for avatars. (The filename is longer than the file :) ) same thing as for avatars. (The filename is longer than the file :) )
@ -273,7 +273,7 @@ Given the Tox data directory described in STS Draft v0.1.0:
upper case strings, but lower case file names are more usual. upper case strings, but lower case file names are more usual.
Example for Linux and other Unix systems, assuming an user called "gildor": Example for Linux and other Unix systems, assuming a user called "gildor":
Tox data directory: /home/gildor/.config/tox/ Tox data directory: /home/gildor/.config/tox/
Tox data file: /home/gildor/.config/tox/data Tox data file: /home/gildor/.config/tox/data
@ -294,13 +294,13 @@ This recommendation is partially implemented by "testing/test_avatars.c".
### Common operations ### Common operations
These are minimal examples of how perform common operations with avatar These are minimal examples of how to perform common operations with avatar
functions. For a complete, working, example, see `testing/test_avatars.c`. functions. For a complete working example, see `testing/test_avatars.c`.
#### Setting an avatar for the current user #### Setting an avatar for the current user
In this example `load_data_file` is just an hypothetical function that loads In this example, `load_data_file` is just a hypothetical function that loads
data from a file into the buffer and sets the length accordingly. data from a file into the buffer and sets the length accordingly.
uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH]; uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH];
@ -313,7 +313,7 @@ data from a file into the buffer and sets the length accordingly.
If the user is connected, this function will also notify all connected If the user is connected, this function will also notify all connected
friends about the avatar change. friends about the avatar change.
If the user already have an avatar defined in the client configuration, it If the user already has an avatar defined in the client configuration, it
must be set before connecting to the network to avoid spurious avatar change must be set before connecting to the network to avoid spurious avatar change
notifications and unnecessary data transfers. notifications and unnecessary data transfers.
@ -327,7 +327,7 @@ To remove the current avatar, an application must call
tox_unset_avatar(tox); tox_unset_avatar(tox);
the effect is the same as setting the avatar format to `TOX_AVATAR_FORMAT_NONE` the effect is the same as setting the avatar format to `TOX_AVATAR_FORMAT_NONE`
and with no data: with no data:
tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0); tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
@ -357,7 +357,7 @@ As in this example:
printf("\n"); printf("\n");
} }
And, somewhere in the Tox initialization calls, set if as the callback to be And, somewhere in the Tox initialization calls, set it as the callback to be
triggered when an avatar information event arrives: triggered when an avatar information event arrives:
tox_callback_avatar_info(tox, avatar_info_cb, NULL); tox_callback_avatar_info(tox, avatar_info_cb, NULL);
@ -370,7 +370,7 @@ in the avatar information event and, if needed, request the avatar data.
#### Receiving avatar data from friends #### Receiving avatar data from friends
Avatar data events are only delivered in reply of avatar data requests which Avatar data events are only delivered in reply to avatar data requests, which
**should** only be sent after getting the user avatar information (format **should** only be sent after getting the user avatar information (format
and hash) from an avatar information event and checking it against a local and hash) from an avatar information event and checking it against a local
cache. cache.
@ -388,7 +388,7 @@ checks the local avatar cache and emits an avatar data request if necessary:
delete_avatar_from_cache(tox, friendnumber); delete_avatar_from_cache(tox, friendnumber);
} else { } else {
/* Use the received hash to check if the cached avatar is /* Use the received hash to check if the cached avatar is
still updated. */ still up to date. */
if (!is_user_cached_avatar_updated(tox, friendnumber, hash)) { if (!is_user_cached_avatar_updated(tox, friendnumber, hash)) {
/* User avatar is outdated, send data request */ /* User avatar is outdated, send data request */
tox_request_avatar_data(tox, friendnumber); tox_request_avatar_data(tox, friendnumber);
@ -420,9 +420,9 @@ calls:
tox_callback_avatar_data(tox, avatar_data_cb, NULL); tox_callback_avatar_data(tox, avatar_data_cb, NULL);
In the previous examples, implementation of the functions to check, store In the previous examples, implementation of the functions to check, store,
and retrieve data from the cache were omitted for brevity. These functions and retrieve data from the cache were omitted for brevity. These functions
will also need to get the friend public key (client id) from they friend will also need to get the friend public key (client id) from the friend
number and, usually, convert it from a byte string to a hexadecimal number and, usually, convert it from a byte string to a hexadecimal
string. A complete, yet more complex, example is available in the file string. A complete, yet more complex, example is available in the file
`testing/test_avatars.c`. `testing/test_avatars.c`.
@ -454,7 +454,7 @@ The avatar transfer protocol adds the following new packet types and ids:
### Requesting avatar information ### Requesting avatar information
To request avatar information, an user must send a packet of type To request avatar information, a user must send a packet of type
`PACKET_ID_AVATAR_INFO_REQ`. This packet has no data fields. Upon `PACKET_ID_AVATAR_INFO_REQ`. This packet has no data fields. Upon
receiving this packet, a client which supports avatars should answer with receiving this packet, a client which supports avatars should answer with
a `PACKET_ID_AVATAR_INFO`. The sender must accept that the friend may a `PACKET_ID_AVATAR_INFO`. The sender must accept that the friend may
@ -472,7 +472,7 @@ the following structure:
Packet data size: 33 bytes Packet data size: 33 bytes
[1: uint8_t format][32: uint8_t hash] [1: uint8_t format][32: uint8_t hash]
Where 'format' is the image data format, one of the following: where 'format' is the image data format, one of the following:
0 = AVATAR_FORMAT_NONE (no avatar set) 0 = AVATAR_FORMAT_NONE (no avatar set)
1 = AVATAR_FORMAT_PNG 1 = AVATAR_FORMAT_PNG
@ -492,21 +492,21 @@ connects, in the same way Tox sends name, status and action information.
Transmission of avatar data is a multi-step procedure using three new packet Transmission of avatar data is a multi-step procedure using three new packet
types. types.
- Packet `PACKET_ID_AVATAR_DATA_CONTROL` have the format: - Packet `PACKET_ID_AVATAR_DATA_CONTROL` has the format:
PACKET_ID_AVATAR_DATA_CONTROL (54) PACKET_ID_AVATAR_DATA_CONTROL (54)
Packet data size: 1 byte Packet data size: 1 byte
[1: uint8_t op] [1: uint8_t op]
where 'op' is a code signaling both an operation request or a status where 'op' is a code signaling either an operation request or a status
return, which semantics are explained bellow. The following values are return, the semantics of which are explained below. The following values are
defined: defined:
0 = AVATAR_DATACONTROL_REQ 0 = AVATAR_DATACONTROL_REQ
1 = AVATAR_DATACONTROL_ERROR 1 = AVATAR_DATACONTROL_ERROR
- Packet `PACKET_ID_AVATAR_DATA_START` have the following format: - Packet `PACKET_ID_AVATAR_DATA_START` has the following format:
PACKET_ID_AVATAR_DATA_START (55) PACKET_ID_AVATAR_DATA_START (55)
Packet data size: 37 bytes Packet data size: 37 bytes
@ -515,13 +515,13 @@ types.
where 'format' is the image format, with the same values accepted for where 'format' is the image format, with the same values accepted for
the field 'format' in packet type `PACKET_ID_AVATAR_INFO`, 'hash' is the field 'format' in packet type `PACKET_ID_AVATAR_INFO`, 'hash' is
the SHA-256 cryptographic hash of the avatar raw data and 'data_length' the SHA-256 cryptographic hash of the avatar raw data, and 'data_length'
is the total number of bytes the raw avatar data. is the total number of bytes the raw avatar data.
- Packet `PACKET_ID_AVATAR_DATA_PUSH` has no format structure, just up - Packet `PACKET_ID_AVATAR_DATA_PUSH` has no format structure, just up
to `AVATAR_DATA_MAX_CHUNK_SIZE` bytes of raw avatar image data; this to `AVATAR_DATA_MAX_CHUNK_SIZE` bytes of raw avatar image data; this
value is defined according to the maximum amount of data a Tox crypted value is defined according to the maximum amount of data a Tox encrypted
packet can hold. packet can hold.
@ -534,9 +534,9 @@ from a client "B":
packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to
`AVATAR_DATACONTROL_REQ`. `AVATAR_DATACONTROL_REQ`.
- If "B" accepts this transfer, it answers by sending an - If "B" accepts this transfer, it answers by sending a
`PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and `PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash', and
'data_length' set to the respective values from the current avatar. 'data_length' set to the respective values of the current avatar.
If "B" has no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash' If "B" has no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash'
must be zeroed and 'data_length' must be zero. must be zeroed and 'data_length' must be zero.
@ -545,12 +545,12 @@ from a client "B":
`AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope `AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope
with this. with this.
If "B" have an avatar, it sends a variable number of If "B" has an avatar, it sends a variable number of
`PACKET_ID_AVATAR_DATA_PUSH` packets with the avatar data in a single `PACKET_ID_AVATAR_DATA_PUSH` packets with the avatar data in a single
shot. shot.
- Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it - Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it
has sent a data request to "B". If not, just ignores the packet. has sent a data request to "B". If not, it simply ignores the packet.
If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`, If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`,
it triggers the avatar data callback, and clears all the temporary data, it triggers the avatar data callback, and clears all the temporary data,
@ -559,36 +559,36 @@ from a client "B":
- Upon receiving a `PACKET_ID_AVATAR_DATA_PUSH`, "A" checks if it really - Upon receiving a `PACKET_ID_AVATAR_DATA_PUSH`, "A" checks if it really
sent an avatar data request and if the `PACKET_ID_AVATAR_DATA_START` was sent an avatar data request and if the `PACKET_ID_AVATAR_DATA_START` was
already received. If this conditions are valid, it checks if the total already received. If these conditions were met, it checks if the total
length of the data already stored in the receiving buffer plus the data length of the data already stored in the receiving buffer plus the data
present in the push packet is still less or equal than present in the push packet is still less or equal than
`TOX_AVATAR_MAX_DATA_LENGTH`. If invalid, it replies with a `TOX_AVATAR_MAX_DATA_LENGTH`. If that is not the case, it replies with a
`PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
`AVATAR_DATACONTROL_ERROR`. `AVATAR_DATACONTROL_ERROR`.
If valid, "A" updates the 'bytes_received' counter and concatenates the If valid, "A" updates the 'bytes_received' counter and concatenates the
newly arrived data to the buffer. newly arrived data to the buffer.
Then "A" checks if all the data was already received by comparing the Then "A" checks if all the data has already been received, by comparing the
counter 'bytes_received' with the field 'total_length'. If they are counter 'bytes_received' with the field 'total_length'. If they are
equal, "A" takes a SHA-256 hash of the data and compares it with the equal, "A" takes a SHA-256 hash of the data and compares it with the
hash stored in the field 'hash' received from the first hash stored in the field 'hash' received with the first
`PACKET_ID_AVATAR_DATA_START`. `PACKET_ID_AVATAR_DATA_START`.
If the hashes match, the avatar data was correctly received and "A" If the hashes match, the avatar data was correctly received, and "A"
triggers the avatar data callback, and clears all the temporary data, triggers the avatar data callback and clears all the temporary data,
finishing the process. finishing the process.
If not all data was received, "A" simply waits for more data. If not all data was received, "A" simply waits for more data.
Client "A" is always responsible for controlling the transfer and Client "A" is always responsible for controlling the transfer and
validating the data received. "B" don't need to keep any state for the validating the data received. "B" doesn't need to keep any state for the
protocol, have full control over the data sent and should implement protocol, have full control over the data sent and should implement
some transfer limit for the data it sends. some transfer limit for the data it sends.
- Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' - Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op'
set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and
finishes sending or receiving data. aborts sending or receiving data.
@ -597,33 +597,33 @@ from a client "B":
## Security considerations ## Security considerations
The major security implication of background data transfers of large objects, The major security implication of background data transfers of large objects,
like avatars, is the possibility of exhausting the network resources from a like avatars, is the possibility of exhausting the network resources of a
client. This problem is exacerbated when there is the possibility of an client. This problem is exacerbated when there is the possibility of an
amplification attack as happens, for example, when sending a very small amplification attack, as happens, for example, when sending a very small
avatar request message will force the user to reply with a larger avatar avatar request message will force the user to reply with a larger avatar
data message. data message.
The present proposal mitigates this situation by: The present proposal mitigates this situation by:
- Only transferring data between previously authenticated friends; - only transferring data between previously authenticated friends,
- Enforcing strict limits on the avatar data size; - enforcing strict limits on the avatar data size,
- Providing an alternate, smaller, message to cooperative users refresh - providing an alternate, smaller message for cooperative users to refresh
avatar information when nothing has changed (`PACKET_ID_AVATAR_INFO`); avatar information when nothing has changed (`PACKET_ID_AVATAR_INFO`),
- Having per-friend data transfer limit. As the current protocol still - having a per-friend data transfer limit. As the current protocol still
allows an user to request avatar data again and again, the implementation allows a user to request avatar data again and again, the implementation
limits the amount of data a particular user can request for some time. The limits the amount of data a particular user can request for some time. The
exact values are defined in constants `AVATAR_DATA_TRANSFER_LIMIT` and exact values are defined in constants `AVATAR_DATA_TRANSFER_LIMIT` and
`AVATAR_DATA_TRANSFER_TIMEOUT` in file `Messenger.c`. `AVATAR_DATA_TRANSFER_TIMEOUT` in file `Messenger.c`.
- Making the requester responsible for storing partial data and state - making the requester responsible for storing partial data and state
information; information
Another problem present in the avatars is the possibility of a friend send Another problem present in avatars is the possibility of a friend sending
a maliciously crafted image intended to exploit vulnerabilities in image a maliciously crafted image intended to exploit vulnerabilities in image
decoders. Without an intermediate server to recompress and validate and decoders. Without an intermediate server to recompress, validate, and
convert the images to neutral formats, the client applications must handle convert the images to neutral formats, the client applications must handle
this situation by themselves using stable and secure image libraries and this situation by themselves using stable and secure image libraries and
imposing limits on the maximum amount of system resources the decoding imposing limits on the maximum amount of system resources the decoding