summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-09-22 15:07:14 -0400
committerirungentoo <irungentoo@gmail.com>2014-09-22 15:07:14 -0400
commitb52da45aebe79b54bbd00564a050fcdaca028617 (patch)
tree0eb8011d0e808a57ed024d735690f99df601eda7 /docs
parent900d72f9511790add88313f31b17d6ca8d81a49c (diff)
parentb52eb48c15a06fe198c7c5e0d765cfef8ff4fbdf (diff)
Merge branch 'avatars' of https://github.com/ittner/toxcore
Diffstat (limited to 'docs')
-rw-r--r--docs/Avatars.md611
1 files changed, 611 insertions, 0 deletions
diff --git a/docs/Avatars.md b/docs/Avatars.md
new file mode 100644
index 00000000..97b65c10
--- /dev/null
+++ b/docs/Avatars.md
@@ -0,0 +1,611 @@
1# User avatars in Tox
2
3
4
5## Introduction and rationale
6
7User avatars are small icons or images used to identify users in the friend
8list; they exists in virtually all VoIP and IM protocols and provide an easy
9way to an user identify another in the friend list.
10
11This document describes the implementation of avatars in the Tox protocol,
12according to the following design considerations:
13
14 - Avatars are handled as private information, ie., only exchanged over
15 Tox encrypted channels among previously authenticated friends;
16
17 - The library treats all images as blobs and does not interpret or
18 understands image formats, only ensures that the avatar data sent by
19 an user is correctly received by the other. The client application is
20 responsible for validating, decoding, resizing, and presenting the
21 image to the user.
22
23 - There is a strict limit of 16 KiB to the avatar raw data size -- this
24 seems suitable for practical use as, for example, the raw data of an
25 uncompressed 64 x 64 pixels 24 bpp RGB bitmap is 12288 bytes long; the
26 data limit provides enough space for larger bitmaps if the usual
27 compressed formats are used.
28
29 **Notice:** As designed, this limit can be changed in the future without
30 breaking the protocol compatibility, but clients using the original
31 limit will reject larger avatars;
32
33 - The protocol MUST provide means to allow caching and avoid unnecessary
34 data transfers;
35
36 - Avatars are transfered between clients in a background operation;
37
38 - Avatars are served in a "best effort" basis, without breaking clients
39 who do not support them;
40
41 - The protocol MUST resist to malicious users;
42
43 - The protocol MUST work with both UDP and TCP networks.
44
45
46The Single Tox Standard Draft v.0.1.0 recommends implementing avatars as
47a purely client-side feature through a procedure that can be summarized as
48sending a specially named file as a file transfer request and accepting
49it silently. This procedure can be improved to provide the previously stated
50design considerations, but this requires a higher integration with the core
51protocol. Moving this feature to the core protocol also:
52
53 - Provides a simpler and cleaner interfaces for client applications;
54
55 - Hides protocol complexities from the client;
56
57 - Avoids code duplication and ad-hoc protocols in the clients;
58
59 - Avoids incompatibility between client implementations;
60
61 - Allows important optimizations such as lightweight notification of
62 removed and updated avatars;
63
64 - Plays well with cache schemes;
65
66 - Makes avatar transfer an essentially background operation.
67
68
69
70
71
72
73## High level description
74
75The avatar exchange is implemented with the following new elements in the
76Tox protocol. This is a very high level description and the usage patterns
77expected from client applications are described in Section "Using Avatars
78in Client Applications" and a low level protocol description is available
79in Section "Internal Protocol Description".
80
81 - **Avatar Information Notifications** are events which may be sent by
82 an user to another anytime, but are usually sent after one of them
83 connects to the network, changes his avatar, or in reply to an **avatar
84 information request**. They are delivered by a very lightweight message
85 but with information enough to allow an user to validate or discard an
86 avatar from the local cache and decide if is interesting to request the
87 avatar data from the peer.
88
89 This event contain two data fields: (1) the image format and (2) the
90 cryptographic hash of the actual image data. Image format may be NONE
91 (for users who have no avatar or removed their avatars) or PNG. The
92 cryptographic hash is intended to be compared with the hash o the
93 currently cached avatar (if any) and check if it stills up to date.
94
95 - **Avatar Information Requests** are very lightweight messages sent by an
96 user asking for an **avatar information notification**. They may be sent
97 as part of the login process or when the client thinks the currently
98 cached avatar is outdated. The receiver may or may not answer to this
99 request. This message contains no data fields;
100
101 - An **Avatar Data Request** is sent by an user asking another for his
102 complete avatar data. It is sent only when the requesting user decides
103 the avatar do not exists in the local cache or is outdated. The receiver
104 may or may not answer to this request. This message contains no data
105 fields.
106
107 - An **Avatar Data Notification** is an event signaling the client that
108 the complete avatar image data of another user is available. The actual
109 data transfer is implemented using several data and control messages,
110 but the details are hidden from the client applications. This event can
111 only arrive in reply to an **avatar data request**.
112
113 This event contains three data fields: (1) the image format, (2) the
114 cryptographic hash of the image data, and (3) the raw image data. If the
115 image format is NONE (i.e. no avatar) the hash is zeroed and the image
116 data is empty. The raw image data is locally validated and ensured to
117 match the hash (the event is **not** triggered otherwise).
118
119
120
121
122
123## API
124
125To implement this feature, the following public symbols were added. The
126complete API documentation is available in `tox.h`.
127
128
129```
130#define TOX_MAX_AVATAR_DATA_LENGTH 16384
131#define TOX_AVATAR_HASH_LENGTH 32
132
133
134/* Data formats for user avatar images */
135typedef enum {
136 TOX_AVATARFORMAT_NONE,
137 TOX_AVATARFORMAT_PNG
138}
139TOX_AVATARFORMAT;
140
141
142
143/* Set the user avatar image data. */
144int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length);
145
146/* Get avatar data from the current user. */
147int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash);
148
149/* Generates a cryptographic hash of the given avatar data. */
150int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen);
151
152/* Request avatar information from a friend. */
153int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber);
154
155/* Send an unrequested avatar information to a friend. */
156int tox_send_avatar_info(Tox *tox, const int32_t friendnumber);
157
158/* Request the avatar data from a friend. */
159int tox_request_avatar_data(const Tox *tox, const int32_t friendnumber);
160
161/* Set the callback function for avatar data. */
162void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t*, void *), void *userdata);
163
164/* Set the callback function for avatar data. */
165void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t*, uint8_t*, uint32_t, void *), void *userdata);
166```
167
168
169
170
171## Using Avatars in Client Applications
172
173
174### General recommendations
175
176 - Clients MUST NOT imply the availability of avatars in other users.
177 Avatars are an optional feature and not all users and clients may
178 support them;
179
180 - Clients MUST NOT block waiting for avatar information and avatar data
181 packets;
182
183 - Clients MUST treat avatar data as insecure and potentially malicious;
184 For example, users may accidentally use corrupted images as avatars,
185 a malicious user may send a specially crafted image to exploit a know
186 vulnerability in an image decoding library, etc. It is recommended to
187 handle the avatar image data in the same way as an image downloaded
188 from an unknown Internet source;
189
190 - The peers MUST NOT assume any coupling between the operations of
191 receiving an avatar information packet, sending unrequested avatar
192 information packets, requesting avatar data, or receiving avatar data.
193
194 For example, the following situations are valid:
195
196 * A text-mode client may send avatars to other users, but never
197 request them;
198
199 * A client may not understand a particular image format and ignore
200 avatars using it, but request and handle other formats;
201
202 - Clients SHOULD implement a local cache of avatars and do not request
203 avatar data from other peers unless necessary;
204
205 - When an avatar information is received, the client should delete the
206 avatar if the new avatar format is NONE or compare the hash received
207 from the peer with the hash of the currently cached avatar. If they
208 differ, send an avatar data request;
209
210 - If the cached avatar is older than a given threshold, the client may
211 also send an avatar info request to that friend once he is online and
212 mark the avatar as updated *before* any avatar information is received
213 (to not spam the peer with such requests);
214
215 - When an avatar data notification is received, the client must update
216 the cached avatar with the new one;
217
218 - Clients should resize or crop the image to the way it better adapts
219 to the client user interface;
220
221 - If the user already have an avatar defined in the client configuration,
222 it must be set before connecting to the network to avoid spurious avatar
223 change notifications and unnecessary data transfers.
224
225 - If no avatar data is available for a given friend, the client should
226 show a placeholder image.
227
228
229
230### Interoperability and sharing avatars among different clients
231
232**This section is a tentative recommendation of how clients should store
233avatars to ensure local interoperability and should be revised if this
234code is accepted into Tox core.**
235
236It is desirable that the user avatar and the cached friends avatars could be
237shared among different Tox clients in the same system, in the spirit of the
238proposed Single Tox Standard. This not only makes switching from one client
239to another easier, but also minimizes the need of data transfers, as avatars
240already downloaded by other clients can be reused.
241
242Given the Tox data directory described in STS Draft v0.1.0:
243
244 - The user avatar is stored in a file named "avatar.png". As more formats
245 may be used in the future, another extensions are reserved and clients
246 should keep just one file named "avatar.*", with the data of the last
247 avatar set by the user. If the user have no avatar, no such files should
248 be kept in the data directory;
249
250 - Friends avatars are stored in a directory called "avatars" and named
251 as "xxxxx.png", where "xxxxx" is the complete client id encoded as an
252 uppercase hexadecimal string and "png" is the extension for the PNG
253 avatar. As new image formats may be used in the future, clients should
254 ensure no other file "xxxxx.*" exists. No file should be kept for an user
255 who have no avatar.
256
257 **To be discussed:** User keys are usually presented in Tox clients as
258 upper case strings, but lower case file names are more usual.
259
260
261Example for Linux and other Unix systems, assuming an user called "gildor":
262
263 Tox data directory: /home/gildor/.config/tox/
264 Tox data file: /home/gildor/.config/tox/data
265 Gildor's avatar: /home/gildor/.config/tox/avatar.png
266 Avatar data dir: /home/gildor/.config/tox/avatars/
267 Elrond's avatar: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.png
268 Elladan's avatar: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.png
269 Elrohir's avatar /home/gildor/.config/tox/avatars/726568746F7242794D6D41496B6E696854736E616D75486E6568576574614849.png
270 Arwen's avatar: /home/gildor/.config/tox/avatars/53686520746F6F6B20476C6F7266696E64656C277320706C6163652068657265.png
271 Lindir's avatar: /home/gildor/.config/tox/avatars/417070735772697474656E42794D6F7274616C734C6F6F6B54686553616D652E.png
272
273This recommendation is partially implemented by "testing/test_avatars.c".
274
275
276
277
278
279### Common operations
280
281These are minimal examples of how perform common operations with avatar
282functions. For a complete, working, example, see `testing/test_avatars.c`.
283
284
285#### Setting an avatar for the current user
286
287In this example `load_data_file` is just an hypothetical function that loads
288data from a file into the buffer and sets the length accordingly.
289
290 uint8_t buf[TOX_MAX_AVATAR_DATA_LENGTH];
291 uint32_t len;
292
293 if (load_data_file("avatar.png", buf, &len) == 0)
294 if (tox_set_avatar(tox, TOX_AVATARFORMAT_PNG, buf, len) != 0)
295 fprintf(stderr, "Failed to set avatar.\n");
296
297If the user is connected, this function will also notify all connected
298friends about the avatar change.
299
300If the user already have an avatar defined in the client configuration, it
301must be set before connecting to the network to avoid spurious avatar change
302notifications and unnecessary data transfers.
303
304
305
306
307#### Removing the avatar from the current user
308
309To remove an avatar, an application must set it to `TOX_AVATARFORMAT_NONE`.
310
311 tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0);
312
313If the user is connected, this function will also notify all connected
314friends about the avatar change.
315
316
317
318
319
320#### Receiving avatar information from friends
321
322All avatar information is passed to a callback function with the prototype:
323
324 void function(Tox *tox, int32_t friendnumber, uint8_t format,
325 uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
326
327As in this example:
328
329 static void avatar_info_cb(Tox *tox, int32_t friendnumber, uint8_t format,
330 uint8_t *hash, void *userdata)
331 {
332 printf("Receiving avatar information from friend %d. Format = %d\n",
333 friendnumber, format);
334 printf("Data hash: ");
335 hex_printf(hash, TOX_AVATAR_HASH_LENGTH); /* Hypothetical function */
336 printf("\n");
337 }
338
339And, somewhere in the Tox initialization calls, set if as the callback to be
340triggered when an avatar information event arrives:
341
342 tox_callback_avatar_info(tox, avatar_info_cb, NULL);
343
344
345A typical client will test the currently cached avatar against the hash given
346in the avatar information event and, if needed, request the avatar data.
347
348
349
350#### Receiving avatar data from friends
351
352Avatar data events are only delivered in reply of avatar data requests which
353**should** only be sent after getting the user avatar information (format
354and hash) from an avatar information event and checking it against a local
355cache.
356
357For this, an application must define an avatar information callback which
358checks the local avatar cache and emits an avatar data request if necessary:
359
360 static void avatar_info_cb(Tox *tox, int32_t friendnumber, uint8_t format,
361 uint8_t *hash, void *userdata)
362 {
363 printf("Receiving avatar information from friend %d. Format = %d\n",
364 friendnumber, format);
365 if (format = TOX_AVATARFORMAT_NONE) {
366 /* User have no avatar or removed the avatar */
367 delete_avatar_from_cache(tox, friendnumber);
368 } else {
369 /* Use the received hash to check if the cached avatar is
370 still updated. */
371 if (!is_user_cached_avatar_updated(tox, friendnumber, hash)) {
372 /* User avatar is outdated, send data request */
373 tox_request_avatar_data(tox, friendnumber);
374 }
375 }
376 }
377
378
379Then define an avatar data callback to store the received data in the local
380cache:
381
382 static void avatar_data_cb(Tox *tox, int32_t friendnumber, uint8_t format,
383 uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
384 {
385 if (format = TOX_AVATARFORMAT_NONE) {
386 /* User have no avatar or removed the avatar */
387 delete_avatar_from_cache(tox, friendnumber);
388 } else {
389 save_avatar_data_to_cache(tox, friendnumber, format, hash,
390 data, datalen);
391 }
392 }
393
394
395And, finally, register both callbacks somewhere in the Tox initialization
396calls:
397
398 tox_callback_avatar_info(tox, avatar_info_cb, NULL);
399 tox_callback_avatar_data(tox, avatar_data_cb, NULL);
400
401
402In the previous examples, implementation of the functions to check, store
403and retrieve data from the cache were omitted for brevity. These functions
404will also need to get the friend client ID (public key) from they friend
405number and, usually, convert it from a byte string to a hexadecimal
406string. A complete, yet more complex, example is available in the file
407`testing/test_avatars.c`.
408
409
410
411
412
413
414
415
416
417
418
419## Internal Protocol Description
420
421### New packet types
422
423The avatar transfer protocol adds the following new packet types and ids:
424
425 PACKET_ID_AVATAR_INFO_REQ = 52
426 PACKET_ID_AVATAR_INFO = 53
427 PACKET_ID_AVATAR_DATA_CONTROL = 54
428 PACKET_ID_AVATAR_DATA_START = 55
429 PACKET_ID_AVATAR_DATA_PUSH = 56
430
431
432
433
434### Requesting avatar information
435
436To request avatar information, an user must send a packet of type
437`PACKET_ID_AVATAR_INFO_REQ`. This packet have no data fields. Upon
438receiving this packet, a client which supports avatars should answer with
439a `PACKET_ID_AVATAR_INFO`. The sender must accept that the friend may
440not answer at all.
441
442
443
444
445### Receiving avatar information
446
447Avatar information arrives in a packet of type `PACKET_ID_AVATAR_INFO` with
448the following structure:
449
450 PACKET_ID_AVATAR_INFO (53)
451 Packet data size: 33 bytes
452 [1: uint8_t format][32: uint8_t hash]
453
454Where 'format' is the image data format, one of the following:
455
456 0 = AVATARFORMAT_NONE (no avatar set)
457 1 = AVATARFORMAT_PNG
458
459and 'hash' is the SHA-256 message digest of the avatar data.
460
461This packet may be sent at any time and no previous request is required.
462Clients should send this packet upon connection or when a friend
463connects, in the same way Tox sends name, status and action information.
464
465
466
467
468
469### Requesting avatar data
470
471Transmission of avatar data is a multi-step procedure using three new packet
472types.
473
474 - Packet `PACKET_ID_AVATAR_DATA_CONTROL` have the format:
475
476 PACKET_ID_AVATAR_DATA_CONTROL (54)
477 Packet data size: 1 byte
478 [1: uint8_t op]
479
480 where 'op' is a code signaling both an operation request or a status
481 return, which semantics are explained bellow. The following values are
482 defined:
483
484 0 = AVATARDATACONTROL_REQ
485 1 = AVATARDATACONTROL_ERROR
486
487
488 - Packet `PACKET_ID_AVATAR_DATA_START` have the following format:
489
490 PACKET_ID_AVATAR_DATA_START (55)
491 Packet data size: 37 bytes
492 [1: uint8_t format][32: uint8_t hash][1: uint32_t data_length]
493
494
495 where 'format' is the image format, with the same values accepted for
496 the field 'format' in packet type `PACKET_ID_AVATAR_INFO`, 'hash' is
497 the SHA-256 cryptographic hash of the avatar raw data and 'data_length'
498 is the total number of bytes the raw avatar data.
499
500
501 - Packet `PACKET_ID_AVATAR_DATA_PUSH` have no format structure, just up
502 to `AVATAR_DATA_MAX_CHUNK_SIZE` bytes of raw avatar image data; this
503 value is defined according to the maximum amount of data a Tox crypted
504 packet can hold.
505
506
507
508The following procedure assumes that a client "A" is requesting avatar data
509from a client "B":
510
511 - "A" must initialize its control structures and mark its data transfer
512 as not yet started. Then it requests avatar data from "B" by sending a
513 packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to
514 `AVATARDATACONTROL_REQ`.
515
516 - If "B" accepts this transfer, it answers by sending an
517 `PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and
518 'data_length' set to the respective values from the current avatar.
519 If "B" have no avatar set, 'format' must be `AVATARFORMAT_NONE`, 'hash'
520 must be zeroed and 'data_length' must be zero.
521
522 If "B" does not accept sending the avatar, it may send a packet
523 `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
524 `AVATARDATACONTROL_ERROR` or simply ignore this request. "A" must cope
525 with this.
526
527 If "B" have an avatar, it sends a variable number of
528 `PACKET_ID_AVATAR_DATA_PUSH` packets with the avatar data in a single
529 shot.
530
531 - Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it
532 has sent a data request to "B". If not, just ignores the packet.
533
534 If "A" really requested avatar data and the format is `AVATARFORMAT_NONE`,
535 it triggers the avatar data callback, and clears all the temporary data,
536 finishing the process. For other formats, "A" just waits for packets
537 of type `PACKET_ID_AVATAR_DATA_PUSH`.
538
539 - Upon receiving a `PACKET_ID_AVATAR_DATA_PUSH`, "A" checks if it really
540 sent an avatar data request and if the `PACKET_ID_AVATAR_DATA_START` was
541 already received. If this conditions are valid, it checks if the total
542 length of the data already stored in the receiving buffer plus the data
543 present in the push packet is still less or equal than
544 `TOX_MAX_AVATAR_DATA_LENGTH`. If invalid, it replies with a
545 `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
546 `AVATARDATACONTROL_ERROR`.
547
548 If valid, "A" updates the 'bytes_received' counter and concatenates the
549 newly arrived data to the buffer.
550
551 The "A" checks if all the data was already received by comparing the
552 counter 'bytes_received' with the field 'total_length'. If they are
553 equal, "A" takes a SHA-256 hash of the data and compares it with the
554 hash stored in the field 'hash' received from the first
555 `PACKET_ID_AVATAR_DATA_START`.
556
557 If the hashes match, the avatar data was correctly received and "A"
558 triggers the avatar data callback, and clears all the temporary data,
559 finishing the process.
560
561 If not all data was received, "A" simply waits for more data.
562
563 Client "A" is always responsible for controlling the transfer and
564 validating the data received. "B" don't need to keep any state for the
565 protocol, have full control over the data sent and should implement
566 some transfer limit for the data it sends.
567
568 - Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op'
569 set to `AVATARDATACONTROL_ERROR` clears any existing control state and
570 finishes sending or receiving data.
571
572
573
574
575
576## Security considerations
577
578The major security implication of background data transfers of large objects,
579like avatars, is the possibility of exhausting the network resources from a
580client. This problem is exacerbated when there is the possibility of an
581amplification attack as happens, for example, when sending a very small
582avatar request message will force the user to reply with a larger avatar
583data message.
584
585The present proposal mitigates this situation by:
586
587 - Only transferring data between previously authenticated friends;
588
589 - Enforcing strict limits on the avatar data size;
590
591 - Providing an alternate, smaller, message to cooperative users refresh
592 avatar information when nothing has changed (`PACKET_ID_AVATAR_INFO`);
593
594 - Having per-friend data transfer limit. As the current protocol still
595 allows an user to request an infinite data stream by asking the the
596 same offset of the avatar again and again, the implementation limits
597 the amount of data a single user can request for some time. For now,
598 the library will not allow an user to request more than
599 `10*TOX_MAX_AVATAR_DATA_LENGTH` in less than 20 minutes;
600
601 - Making the requester responsible for storing partial data and state
602 information;
603
604Another problem present in the avatars is the possibility of a friend send
605a maliciously crafted image intended to exploit vulnerabilities in image
606decoders. Without an intermediate server to recompress and validate and
607convert the images to neutral formats, the client applications must handle
608this situation by themselves using stable and secure image libraries and
609imposing limits on the maximum amount of system resources the decoding
610process can take. Images coming from Tox friends must be treated in the same
611way as images coming from random Internet sources.