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