Integer type name change.
[silc.git] / lib / silcclient / client_channel.c
1 /*
2
3   client_channel.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2001 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /* $Id$ */
21 /* This file includes channel message sending and receiving routines,
22    channel key receiving and setting, and channel private key handling 
23    routines. */
24
25 #include "silcincludes.h"
26 #include "silcclient.h"
27 #include "client_internal.h"
28
29 /* Sends packet to the `channel'. Packet to channel is always encrypted
30    differently from "normal" packets. SILC header of the packet is 
31    encrypted with the next receiver's key and the rest of the packet is
32    encrypted with the channel specific key. Padding and HMAC is computed
33    with the next receiver's key. The `data' is the channel message. If
34    the `force_send' is TRUE then the packet is sent immediately. */
35
36 void silc_client_send_channel_message(SilcClient client, 
37                                       SilcClientConnection conn,
38                                       SilcChannelEntry channel,
39                                       SilcChannelPrivateKey key,
40                                       SilcMessageFlags flags,
41                                       unsigned char *data, 
42                                       SilcUInt32 data_len, 
43                                       int force_send)
44 {
45   int i;
46   SilcSocketConnection sock = conn->sock;
47   SilcBuffer payload;
48   SilcPacketContext packetdata;
49   SilcCipher cipher;
50   SilcHmac hmac;
51   unsigned char *id_string;
52   SilcUInt32 iv_len;
53   int block_len;
54
55   SILC_LOG_DEBUG(("Sending packet to channel"));
56
57   /* Take the key to be used */
58   if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
59     if (key) {
60       /* Use key application specified */
61       cipher = key->cipher;
62       hmac = key->hmac;
63     } else if (channel->curr_key) {
64       /* Use current private key */
65       cipher = channel->curr_key->cipher;
66       hmac = channel->curr_key->hmac;
67     } else if (!channel->curr_key && channel->private_keys) {
68       /* Use just some private key since we don't know what to use 
69          and private keys are set. */
70       silc_dlist_start(channel->private_keys);
71       key = silc_dlist_get(channel->private_keys);
72       cipher = key->cipher;
73       hmac = key->hmac;
74       
75       /* Use this key as current private key */
76       channel->curr_key = key;
77     } else {
78       /* Use normal channel key generated by the server */
79       cipher = channel->channel_key;
80       hmac = channel->hmac;
81     }
82   } else {
83     /* Use normal channel key generated by the server */
84     cipher = channel->channel_key;
85     hmac = channel->hmac;
86   }
87
88   if (!cipher || !hmac)
89     return;
90
91   block_len = silc_cipher_get_block_len(cipher);
92
93   /* Generate IV */
94   iv_len = silc_cipher_get_block_len(cipher);
95   if (channel->iv[0] == '\0')
96     for (i = 0; i < iv_len; i++) channel->iv[i] = 
97                                    silc_rng_get_byte(client->rng);
98   else
99     silc_hash_make(client->internal->md5hash, channel->iv, iv_len, 
100                    channel->iv);
101
102   /* Encode the channel payload. This also encrypts the message payload. */
103   payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len, 
104                                                 channel->iv, cipher, hmac);
105
106   /* Get data used in packet header encryption, keys and stuff. */
107   cipher = conn->send_key;
108   hmac = conn->hmac_send;
109   id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
110
111   /* Set the packet context pointers. The destination ID is always
112      the Channel ID of the channel. Server and router will handle the
113      distribution of the packet. */
114   packetdata.flags = 0;
115   packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
116   packetdata.src_id = conn->local_id_data;
117   packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
118   packetdata.src_id_type = SILC_ID_CLIENT;
119   packetdata.dst_id = id_string;
120   packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
121   packetdata.dst_id_type = SILC_ID_CHANNEL;
122   packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN + 
123     packetdata.src_id_len + packetdata.dst_id_len;
124   packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
125                                           packetdata.src_id_len +
126                                           packetdata.dst_id_len), block_len);
127
128   /* Prepare outgoing data buffer for packet sending */
129   silc_packet_send_prepare(sock, 
130                            SILC_PACKET_HEADER_LEN +
131                            packetdata.src_id_len + 
132                            packetdata.dst_id_len,
133                            packetdata.padlen,
134                            payload->len);
135
136   packetdata.buffer = sock->outbuf;
137
138   /* Put the channel message payload to the outgoing data buffer */
139   silc_buffer_put(sock->outbuf, payload->data, payload->len);
140
141   /* Create the outgoing packet */
142   silc_packet_assemble(&packetdata, cipher);
143
144   /* Encrypt the header and padding of the packet. This is encrypted 
145      with normal session key shared with our server. */
146   silc_packet_encrypt(cipher, hmac, conn->psn_send++,
147                       sock->outbuf, SILC_PACKET_HEADER_LEN + 
148                       packetdata.src_id_len + packetdata.dst_id_len +
149                       packetdata.padlen);
150
151   SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
152                    sock->outbuf->data, sock->outbuf->len);
153
154   /* Now actually send the packet */
155   silc_client_packet_send_real(client, sock, force_send);
156   silc_buffer_free(payload);
157   silc_free(id_string);
158 }
159
160 typedef struct {
161   SilcChannelMessagePayload payload;
162   SilcChannelID *channel_id;
163 } *SilcChannelClientResolve;
164
165 static void silc_client_channel_message_cb(SilcClient client,
166                                            SilcClientConnection conn,
167                                            SilcClientEntry *clients,
168                                            SilcUInt32 clients_count,
169                                            void *context)
170 {
171   SilcChannelClientResolve res = (SilcChannelClientResolve)context;
172
173   if (clients_count == 1) {
174     SilcChannelEntry channel;
175     unsigned char *message;
176
177     channel = silc_client_get_channel_by_id(client, conn, res->channel_id);
178     if (!channel)
179       goto out;
180
181     /* If this client is not on channel, add it there since it clearly
182        is there. */
183     if (!silc_client_on_channel(channel, clients[0])) {
184       SilcChannelUser chu = silc_calloc(1, sizeof(*chu));
185       chu->client = clients[0];
186       chu->channel = channel;
187       silc_hash_table_add(channel->user_list, clients[0], chu);
188       silc_hash_table_add(clients[0]->channels, channel, chu);
189     }
190
191     message = silc_channel_message_get_data(res->payload, NULL);
192     
193     /* Pass the message to application */
194     client->internal->ops->channel_message(
195                                client, conn, clients[0], channel,
196                                silc_channel_message_get_flags(res->payload),
197                                message);
198   }
199
200  out:
201   silc_channel_message_payload_free(res->payload);
202   silc_free(res->channel_id);
203   silc_free(res);
204 }
205
206 /* Process received message to a channel (or from a channel, really). This
207    decrypts the channel message with channel specific key and parses the
208    channel payload. Finally it displays the message on the screen. */
209
210 void silc_client_channel_message(SilcClient client, 
211                                  SilcSocketConnection sock, 
212                                  SilcPacketContext *packet)
213 {
214   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
215   SilcBuffer buffer = packet->buffer;
216   SilcChannelMessagePayload payload = NULL;
217   SilcChannelID *id = NULL;
218   SilcChannelEntry channel;
219   SilcClientEntry client_entry;
220   SilcClientID *client_id = NULL;
221   unsigned char *message;
222
223   SILC_LOG_DEBUG(("Start"));
224
225   /* Sanity checks */
226   if (packet->dst_id_type != SILC_ID_CHANNEL)
227     goto out;
228
229   client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
230                              SILC_ID_CLIENT);
231   if (!client_id)
232     goto out;
233   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
234   if (!id)
235     goto out;
236
237   /* Find the channel entry from channels on this connection */
238   channel = silc_client_get_channel_by_id(client, conn, id);
239   if (!channel)
240     goto out;
241
242   /* If there is no channel private key then just decrypt the message 
243      with the channel key. If private keys are set then just go through
244      all private keys and check what decrypts correctly. */
245   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
246     /* Parse the channel message payload. This also decrypts the payload */
247     payload = silc_channel_message_payload_parse(buffer->data, buffer->len, 
248                                                  channel->channel_key,
249                                                  channel->hmac);
250
251     /* If decryption failed and we have just performed channel key rekey
252        we will use the old key in decryption. If that fails too then we
253        cannot do more and will drop the packet. */
254     if (!payload) {
255       if (!channel->old_channel_key) {
256         goto out;
257       }
258
259       payload = silc_channel_message_payload_parse(buffer->data, buffer->len, 
260                                                    channel->old_channel_key,
261                                                    channel->old_hmac);
262       if (!payload) {
263         goto out;
264       }
265     }
266   } else if (channel->private_keys) {
267     SilcChannelPrivateKey entry;
268
269     silc_dlist_start(channel->private_keys);
270     while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
271       /* Parse the channel message payload. This also decrypts the payload */
272       payload = silc_channel_message_payload_parse(buffer->data, buffer->len, 
273                                                    entry->cipher,
274                                                    entry->hmac);
275       if (payload)
276         break;
277     }
278     if (entry == SILC_LIST_END)
279       goto out;
280   } else {
281     goto out;
282   }
283
284   /* Find client entry */
285   client_entry = silc_client_get_client_by_id(client, conn, client_id);
286   if (!client_entry || !client_entry->nickname) {
287     /* Resolve the client info */
288     SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
289     res->payload = payload;
290     res->channel_id = id;
291     silc_client_get_client_by_id_resolve(client, conn, client_id,
292                                          silc_client_channel_message_cb,
293                                          res);
294     payload = NULL;
295     id = NULL;
296     goto out;
297   }
298
299   if (!silc_client_on_channel(channel, client_entry)) {
300     SILC_LOG_WARNING(("Received channel message from client not on channel"));
301     goto out;
302   }
303
304   message = silc_channel_message_get_data(payload, NULL);
305
306   /* Pass the message to application */
307   client->internal->ops->channel_message(
308                                  client, conn, client_entry, channel,
309                                  silc_channel_message_get_flags(payload),
310                                  message);
311
312  out:
313   silc_free(id);
314   silc_free(client_id);
315   if (payload)
316     silc_channel_message_payload_free(payload);
317 }
318
319 /* Timeout callback that is called after a short period of time after the
320    new channel key has been created. This removes the old channel key all
321    together. */
322
323 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
324 {
325   SilcChannelEntry channel = (SilcChannelEntry)context;
326
327   if (channel->old_channel_key)
328     silc_cipher_free(channel->old_channel_key);
329   if (channel->old_hmac)
330     silc_hmac_free(channel->old_hmac);
331   channel->old_channel_key = NULL;
332   channel->old_hmac = NULL;
333   channel->rekey_task = NULL;
334 }
335
336 /* Saves channel key from encoded `key_payload'. This is used when we
337    receive Channel Key Payload and when we are processing JOIN command 
338    reply. */
339
340 void silc_client_save_channel_key(SilcClient client,
341                                   SilcClientConnection conn,
342                                   SilcBuffer key_payload, 
343                                   SilcChannelEntry channel)
344 {
345   unsigned char *id_string, *key, *cipher, *hmac, hash[32];
346   SilcUInt32 tmp_len;
347   SilcChannelID *id;
348   SilcChannelKeyPayload payload;
349
350   payload = silc_channel_key_payload_parse(key_payload->data,
351                                            key_payload->len);
352   if (!payload)
353     return;
354
355   id_string = silc_channel_key_get_id(payload, &tmp_len);
356   if (!id_string) {
357     silc_channel_key_payload_free(payload);
358     return;
359   }
360
361   id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
362   if (!id) {
363     silc_channel_key_payload_free(payload);
364     return;
365   }
366
367   /* Find channel. */
368   if (!channel) {
369     channel = silc_client_get_channel_by_id(client, conn, id);
370     if (!channel)
371       goto out;
372   }
373
374   hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : 
375           SILC_DEFAULT_HMAC);
376
377   /* Save the old key for a short period of time so that we can decrypt
378      channel message even after the rekey if some client would be sending
379      messages with the old key after the rekey. */
380   if (channel->old_channel_key)
381     silc_cipher_free(channel->old_channel_key);
382   if (channel->old_hmac)
383     silc_hmac_free(channel->old_hmac);
384   if (channel->rekey_task)
385     silc_schedule_task_del(client->schedule, channel->rekey_task);
386   channel->old_channel_key = channel->channel_key;
387   channel->old_hmac = channel->hmac;
388   channel->rekey_task = 
389     silc_schedule_task_add(client->schedule, 0,
390                            silc_client_save_channel_key_rekey, channel,
391                            10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
392
393   /* Free the old channel key data */
394   silc_free(channel->key);
395
396   /* Save the key */
397   key = silc_channel_key_get_key(payload, &tmp_len);
398   cipher = silc_channel_key_get_cipher(payload, NULL);
399   channel->key_len = tmp_len * 8;
400   channel->key = silc_memdup(key, tmp_len);
401
402   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
403     client->internal->ops->say(
404                            conn->client, conn, 
405                            SILC_CLIENT_MESSAGE_AUDIT,
406                            "Cannot talk to channel: unsupported cipher %s", 
407                            cipher);
408     goto out;
409   }
410
411   /* Set the cipher key */
412   silc_cipher_set_key(channel->channel_key, key, channel->key_len);
413
414   /* Generate HMAC key from the channel key data and set it */
415   silc_hmac_alloc(hmac, NULL, &channel->hmac);
416   silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
417   silc_hmac_set_key(channel->hmac, hash, 
418                     silc_hash_len(silc_hmac_get_hash(channel->hmac)));
419   memset(hash, 0, sizeof(hash));
420
421  out:
422   silc_free(id);
423   silc_channel_key_payload_free(payload);
424 }
425
426 /* Processes received key for channel. The received key will be used
427    to protect the traffic on the channel for now on. Client must receive
428    the key to the channel before talking on the channel is possible. 
429    This is the key that server has generated, this is not the channel
430    private key, it is entirely local setting. */
431
432 void silc_client_receive_channel_key(SilcClient client,
433                                      SilcSocketConnection sock,
434                                      SilcBuffer packet)
435 {
436   SILC_LOG_DEBUG(("Received key for channel"));
437
438   /* Save the key */
439   silc_client_save_channel_key(client, sock->user_data, packet, NULL);
440 }
441
442 /* Adds private key for channel. This may be set only if the channel's mode
443    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
444    mode is not set. When channel has private key then the messages are
445    encrypted using that key. All clients on the channel must also know the
446    key in order to decrypt the messages. However, it is possible to have
447    several private keys per one channel. In this case only some of the
448    clients on the channel may know the one key and only some the other key.
449
450    If `cipher' and/or `hmac' is NULL then default values will be used 
451    (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
452
453    The private key for channel is optional. If it is not set then the
454    channel messages are encrypted using the channel key generated by the
455    server. However, setting the private key (or keys) for the channel 
456    significantly adds security. If more than one key is set the library
457    will automatically try all keys at the message decryption phase. Note:
458    setting many keys slows down the decryption phase as all keys has to
459    be tried in order to find the correct decryption key. However, setting
460    a few keys does not have big impact to the decryption performace. 
461
462    NOTE: that this is entirely local setting. The key set using this function
463    is not sent to the network at any phase.
464
465    NOTE: If the key material was originated by the SKE protocol (using
466    silc_client_send_key_agreement) then the `key' MUST be the
467    key->send_enc_key as this is dictated by the SILC protocol. However,
468    currently it is not expected that the SKE key material would be used
469    as channel private key. However, this API allows it. */
470
471 int silc_client_add_channel_private_key(SilcClient client,
472                                         SilcClientConnection conn,
473                                         SilcChannelEntry channel,
474                                         char *cipher,
475                                         char *hmac,
476                                         unsigned char *key,
477                                         SilcUInt32 key_len)
478 {
479   SilcChannelPrivateKey entry;
480   unsigned char hash[32];
481   SilcSKEKeyMaterial *keymat;
482
483   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
484     return FALSE;
485
486   if (!cipher)
487     cipher = SILC_DEFAULT_CIPHER;
488   if (!hmac)
489     hmac = SILC_DEFAULT_HMAC;
490
491   if (!silc_cipher_is_supported(cipher))
492     return FALSE;
493
494   if (!silc_hmac_is_supported(hmac))
495     return FALSE;
496
497   /* Produce the key material */
498   keymat = silc_calloc(1, sizeof(*keymat));
499   if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16, 
500                                          client->internal->md5hash, keymat) 
501       != SILC_SKE_STATUS_OK)
502     return FALSE;
503
504   /* Remove the current key, if it exists. */
505   if (channel->channel_key) {
506     silc_cipher_free(channel->channel_key);
507     memset(channel->key, 0, channel->key_len / 8);
508     silc_free(channel->key);
509     channel->channel_key = NULL;
510     channel->key = NULL;
511     channel->key_len = 0;
512   }
513   if (channel->hmac) {
514     silc_hmac_free(channel->hmac);
515     channel->hmac = NULL;
516   }
517
518   if (!channel->private_keys)
519     channel->private_keys = silc_dlist_init();
520
521   /* Save the key */
522   entry = silc_calloc(1, sizeof(*entry));
523   entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
524   entry->key_len = keymat->enc_key_len / 8;
525
526   /* Allocate the cipher and set the key*/
527   silc_cipher_alloc(cipher, &entry->cipher);
528   silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
529
530   /* Generate HMAC key from the channel key data and set it */
531   silc_hmac_alloc(hmac, NULL, &entry->hmac);
532   silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key, 
533                  entry->key_len, hash);
534   silc_hmac_set_key(entry->hmac, hash, 
535                     silc_hash_len(silc_hmac_get_hash(entry->hmac)));
536   memset(hash, 0, sizeof(hash));
537
538   /* Add to the private keys list */
539   silc_dlist_add(channel->private_keys, entry);
540
541   if (!channel->curr_key)
542     channel->curr_key = entry;
543
544   /* Free the key material */
545   silc_ske_free_key_material(keymat);
546
547   return TRUE;
548 }
549
550 /* Removes all private keys from the `channel'. The old channel key is used
551    after calling this to protect the channel messages. Returns FALSE on
552    on error, TRUE otherwise. */
553
554 int silc_client_del_channel_private_keys(SilcClient client,
555                                          SilcClientConnection conn,
556                                          SilcChannelEntry channel)
557 {
558   SilcChannelPrivateKey entry;
559
560   if (!channel->private_keys)
561     return FALSE;
562
563   silc_dlist_start(channel->private_keys);
564   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
565     silc_dlist_del(channel->private_keys, entry);
566     memset(entry->key, 0, entry->key_len);
567     silc_free(entry->key);
568     silc_cipher_free(entry->cipher);
569     silc_hmac_free(entry->hmac);
570     silc_free(entry);
571   }
572
573   channel->curr_key = NULL;
574
575   silc_dlist_uninit(channel->private_keys);
576   channel->private_keys = NULL;
577
578   return TRUE;
579 }
580
581 /* Removes and frees private key `key' from the channel `channel'. The `key'
582    is retrieved by calling the function silc_client_list_channel_private_keys.
583    The key is not used after this. If the key was last private key then the
584    old channel key is used hereafter to protect the channel messages. This
585    returns FALSE on error, TRUE otherwise. */
586
587 int silc_client_del_channel_private_key(SilcClient client,
588                                         SilcClientConnection conn,
589                                         SilcChannelEntry channel,
590                                         SilcChannelPrivateKey key)
591 {
592   SilcChannelPrivateKey entry;
593
594   if (!channel->private_keys)
595     return FALSE;
596
597   silc_dlist_start(channel->private_keys);
598   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
599     if (entry == key) {
600       if (channel->curr_key == entry)
601         channel->curr_key = NULL;
602
603       silc_dlist_del(channel->private_keys, entry);
604       memset(entry->key, 0, entry->key_len);
605       silc_free(entry->key);
606       silc_cipher_free(entry->cipher);
607       silc_hmac_free(entry->hmac);
608       silc_free(entry);
609
610       if (silc_dlist_count(channel->private_keys) == 0) {
611         silc_dlist_uninit(channel->private_keys);
612         channel->private_keys = NULL;
613       }
614
615       return TRUE;
616     }
617   }
618
619   return FALSE;
620 }
621
622 /* Returns array (pointers) of private keys associated to the `channel'.
623    The caller must free the array by calling the function
624    silc_client_free_channel_private_keys. The pointers in the array may be
625    used to delete the specific key by giving the pointer as argument to the
626    function silc_client_del_channel_private_key. */
627
628 SilcChannelPrivateKey *
629 silc_client_list_channel_private_keys(SilcClient client,
630                                       SilcClientConnection conn,
631                                       SilcChannelEntry channel,
632                                       SilcUInt32 *key_count)
633 {
634   SilcChannelPrivateKey *keys = NULL, entry;
635   SilcUInt32 count = 0;
636
637   if (!channel->private_keys)
638     return NULL;
639
640   silc_dlist_start(channel->private_keys);
641   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
642     keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
643     keys[count] = entry;
644     count++;
645   }
646
647   if (key_count)
648     *key_count = count;
649
650   return keys;
651 }
652
653 /* Frees the SilcChannelPrivateKey array. */
654
655 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
656                                            SilcUInt32 key_count)
657 {
658   silc_free(keys);
659 }
660
661 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the 
662    channel indicated by the `channel'. NULL if client is not joined on
663    the channel. */
664
665 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
666                                        SilcClientEntry client_entry)
667 {
668   SilcChannelUser chu;
669
670   if (silc_hash_table_find(channel->user_list, client_entry, NULL, 
671                            (void *)&chu))
672     return chu;
673
674   return NULL;
675 }