updates.
[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       if (!channel->old_channel_key)
245         goto out;
246
247       payload = silc_channel_message_payload_parse(buffer->data, buffer->len, 
248                                                    channel->old_channel_key,
249                                                    channel->old_hmac);
250       if (!payload)
251         goto out;
252     }
253   } else if (channel->private_keys) {
254     SilcChannelPrivateKey entry;
255
256     silc_dlist_start(channel->private_keys);
257     while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
258       /* Parse the channel message payload. This also decrypts the payload */
259       payload = silc_channel_message_payload_parse(buffer->data, buffer->len, 
260                                                    entry->cipher,
261                                                    entry->hmac);
262       if (payload)
263         break;
264     }
265     if (entry == SILC_LIST_END)
266       goto out;
267   } else {
268     goto out;
269   }
270
271   /* Find client entry */
272   client_entry = silc_client_get_client_by_id(client, conn, client_id);
273   if (!client_entry || !client_entry->nickname) {
274     /* Resolve the client info */
275     SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
276     res->payload = payload;
277     res->channel_id = id;
278     silc_client_get_client_by_id_resolve(client, conn, client_id,
279                                          silc_client_channel_message_cb,
280                                          res);
281     payload = NULL;
282     id = NULL;
283     goto out;
284   }
285
286   if (!silc_client_on_channel(channel, client_entry)) {
287     SILC_LOG_WARNING(("Received channel message from client not on channel"));
288     goto out;
289   }
290
291   message = silc_channel_message_get_data(payload, NULL);
292
293   /* Pass the message to application */
294   client->internal->ops->channel_message(
295                                  client, conn, client_entry, channel,
296                                  silc_channel_message_get_flags(payload),
297                                  message);
298
299  out:
300   silc_free(id);
301   silc_free(client_id);
302   if (payload)
303     silc_channel_message_payload_free(payload);
304 }
305
306 /* Timeout callback that is called after a short period of time after the
307    new channel key has been created. This removes the old channel key all
308    together. */
309
310 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
311 {
312   SilcChannelEntry channel = (SilcChannelEntry)context;
313
314   if (channel->old_channel_key)
315     silc_cipher_free(channel->old_channel_key);
316   if (channel->old_hmac)
317     silc_hmac_free(channel->old_hmac);
318   channel->old_channel_key = NULL;
319   channel->old_hmac = NULL;
320   channel->rekey_task = NULL;
321 }
322
323 /* Saves channel key from encoded `key_payload'. This is used when we
324    receive Channel Key Payload and when we are processing JOIN command 
325    reply. */
326
327 void silc_client_save_channel_key(SilcClient client,
328                                   SilcClientConnection conn,
329                                   SilcBuffer key_payload, 
330                                   SilcChannelEntry channel)
331 {
332   unsigned char *id_string, *key, *cipher, *hmac, hash[32];
333   uint32 tmp_len;
334   SilcChannelID *id;
335   SilcChannelKeyPayload payload;
336
337   payload = silc_channel_key_payload_parse(key_payload->data,
338                                            key_payload->len);
339   if (!payload)
340     return;
341
342   id_string = silc_channel_key_get_id(payload, &tmp_len);
343   if (!id_string) {
344     silc_channel_key_payload_free(payload);
345     return;
346   }
347
348   id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
349   if (!id) {
350     silc_channel_key_payload_free(payload);
351     return;
352   }
353
354   /* Find channel. */
355   if (!channel) {
356     channel = silc_client_get_channel_by_id(client, conn, id);
357     if (!channel)
358       goto out;
359   }
360
361   hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : 
362           SILC_DEFAULT_HMAC);
363
364   /* Save the old key for a short period of time so that we can decrypt
365      channel message even after the rekey if some client would be sending
366      messages with the old key after the rekey. */
367   if (channel->old_channel_key)
368     silc_cipher_free(channel->old_channel_key);
369   if (channel->old_hmac)
370     silc_hmac_free(channel->old_hmac);
371   if (channel->rekey_task)
372     silc_schedule_task_del(client->schedule, channel->rekey_task);
373   channel->old_channel_key = channel->channel_key;
374   channel->old_hmac = channel->hmac;
375   channel->rekey_task = 
376     silc_schedule_task_add(client->schedule, 0,
377                            silc_client_save_channel_key_rekey, channel,
378                            10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
379
380   /* Free the old channel key data */
381   silc_free(channel->key);
382
383   /* Save the key */
384   key = silc_channel_key_get_key(payload, &tmp_len);
385   cipher = silc_channel_key_get_cipher(payload, NULL);
386   channel->key_len = tmp_len * 8;
387   channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
388   memcpy(channel->key, key, tmp_len);
389
390   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
391     client->internal->ops->say(
392                            conn->client, conn, 
393                            SILC_CLIENT_MESSAGE_AUDIT,
394                            "Cannot talk to channel: unsupported cipher %s", 
395                            cipher);
396     goto out;
397   }
398
399   /* Set the cipher key */
400   silc_cipher_set_key(channel->channel_key, key, channel->key_len);
401
402   /* Generate HMAC key from the channel key data and set it */
403   silc_hmac_alloc(hmac, NULL, &channel->hmac);
404   silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
405   silc_hmac_set_key(channel->hmac, hash, 
406                     silc_hash_len(silc_hmac_get_hash(channel->hmac)));
407   memset(hash, 0, sizeof(hash));
408
409  out:
410   silc_free(id);
411   silc_channel_key_payload_free(payload);
412 }
413
414 /* Processes received key for channel. The received key will be used
415    to protect the traffic on the channel for now on. Client must receive
416    the key to the channel before talking on the channel is possible. 
417    This is the key that server has generated, this is not the channel
418    private key, it is entirely local setting. */
419
420 void silc_client_receive_channel_key(SilcClient client,
421                                      SilcSocketConnection sock,
422                                      SilcBuffer packet)
423 {
424   SILC_LOG_DEBUG(("Received key for channel"));
425
426   /* Save the key */
427   silc_client_save_channel_key(client, sock->user_data, packet, NULL);
428 }
429
430 /* Adds private key for channel. This may be set only if the channel's mode
431    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
432    mode is not set. When channel has private key then the messages are
433    encrypted using that key. All clients on the channel must also know the
434    key in order to decrypt the messages. However, it is possible to have
435    several private keys per one channel. In this case only some of the
436    clients on the channel may know the one key and only some the other key.
437
438    If `cipher' and/or `hmac' is NULL then default values will be used 
439    (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
440
441    The private key for channel is optional. If it is not set then the
442    channel messages are encrypted using the channel key generated by the
443    server. However, setting the private key (or keys) for the channel 
444    significantly adds security. If more than one key is set the library
445    will automatically try all keys at the message decryption phase. Note:
446    setting many keys slows down the decryption phase as all keys has to
447    be tried in order to find the correct decryption key. However, setting
448    a few keys does not have big impact to the decryption performace. 
449
450    NOTE: that this is entirely local setting. The key set using this function
451    is not sent to the network at any phase.
452
453    NOTE: If the key material was originated by the SKE protocol (using
454    silc_client_send_key_agreement) then the `key' MUST be the
455    key->send_enc_key as this is dictated by the SILC protocol. However,
456    currently it is not expected that the SKE key material would be used
457    as channel private key. However, this API allows it. */
458
459 int silc_client_add_channel_private_key(SilcClient client,
460                                         SilcClientConnection conn,
461                                         SilcChannelEntry channel,
462                                         char *cipher,
463                                         char *hmac,
464                                         unsigned char *key,
465                                         uint32 key_len)
466 {
467   SilcChannelPrivateKey entry;
468   unsigned char hash[32];
469   SilcSKEKeyMaterial *keymat;
470
471   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
472     return FALSE;
473
474   if (!cipher)
475     cipher = SILC_DEFAULT_CIPHER;
476   if (!hmac)
477     hmac = SILC_DEFAULT_HMAC;
478
479   if (!silc_cipher_is_supported(cipher))
480     return FALSE;
481
482   if (!silc_hmac_is_supported(hmac))
483     return FALSE;
484
485   /* Produce the key material */
486   keymat = silc_calloc(1, sizeof(*keymat));
487   if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16, 
488                                          client->internal->md5hash, keymat) 
489       != SILC_SKE_STATUS_OK)
490     return FALSE;
491
492   /* Remove the current key, if it exists. */
493   if (channel->channel_key) {
494     silc_cipher_free(channel->channel_key);
495     memset(channel->key, 0, channel->key_len / 8);
496     silc_free(channel->key);
497     channel->channel_key = NULL;
498     channel->key = NULL;
499     channel->key_len = 0;
500   }
501   if (channel->hmac) {
502     silc_hmac_free(channel->hmac);
503     channel->hmac = NULL;
504   }
505
506   if (!channel->private_keys)
507     channel->private_keys = silc_dlist_init();
508
509   /* Save the key */
510   entry = silc_calloc(1, sizeof(*entry));
511   entry->key = silc_calloc(keymat->enc_key_len / 8, sizeof(*entry->key));
512   memcpy(entry->key, keymat->send_enc_key, keymat->enc_key_len / 8);
513   entry->key_len = keymat->enc_key_len / 8;
514
515   /* Allocate the cipher and set the key*/
516   silc_cipher_alloc(cipher, &entry->cipher);
517   silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
518
519   /* Generate HMAC key from the channel key data and set it */
520   silc_hmac_alloc(hmac, NULL, &entry->hmac);
521   silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key, 
522                  entry->key_len, hash);
523   silc_hmac_set_key(entry->hmac, hash, 
524                     silc_hash_len(silc_hmac_get_hash(entry->hmac)));
525   memset(hash, 0, sizeof(hash));
526
527   /* Add to the private keys list */
528   silc_dlist_add(channel->private_keys, entry);
529
530   if (!channel->curr_key)
531     channel->curr_key = entry;
532
533   /* Free the key material */
534   silc_ske_free_key_material(keymat);
535
536   return TRUE;
537 }
538
539 /* Removes all private keys from the `channel'. The old channel key is used
540    after calling this to protect the channel messages. Returns FALSE on
541    on error, TRUE otherwise. */
542
543 int silc_client_del_channel_private_keys(SilcClient client,
544                                          SilcClientConnection conn,
545                                          SilcChannelEntry channel)
546 {
547   SilcChannelPrivateKey entry;
548
549   if (!channel->private_keys)
550     return FALSE;
551
552   silc_dlist_start(channel->private_keys);
553   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
554     silc_dlist_del(channel->private_keys, entry);
555     memset(entry->key, 0, entry->key_len);
556     silc_free(entry->key);
557     silc_cipher_free(entry->cipher);
558     silc_hmac_free(entry->hmac);
559     silc_free(entry);
560   }
561
562   channel->curr_key = NULL;
563
564   silc_dlist_uninit(channel->private_keys);
565   channel->private_keys = NULL;
566
567   return TRUE;
568 }
569
570 /* Removes and frees private key `key' from the channel `channel'. The `key'
571    is retrieved by calling the function silc_client_list_channel_private_keys.
572    The key is not used after this. If the key was last private key then the
573    old channel key is used hereafter to protect the channel messages. This
574    returns FALSE on error, TRUE otherwise. */
575
576 int silc_client_del_channel_private_key(SilcClient client,
577                                         SilcClientConnection conn,
578                                         SilcChannelEntry channel,
579                                         SilcChannelPrivateKey key)
580 {
581   SilcChannelPrivateKey entry;
582
583   if (!channel->private_keys)
584     return FALSE;
585
586   silc_dlist_start(channel->private_keys);
587   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
588     if (entry == key) {
589       if (channel->curr_key == entry)
590         channel->curr_key = NULL;
591
592       silc_dlist_del(channel->private_keys, entry);
593       memset(entry->key, 0, entry->key_len);
594       silc_free(entry->key);
595       silc_cipher_free(entry->cipher);
596       silc_hmac_free(entry->hmac);
597       silc_free(entry);
598
599       if (silc_dlist_count(channel->private_keys) == 0) {
600         silc_dlist_uninit(channel->private_keys);
601         channel->private_keys = NULL;
602       }
603
604       return TRUE;
605     }
606   }
607
608   return FALSE;
609 }
610
611 /* Returns array (pointers) of private keys associated to the `channel'.
612    The caller must free the array by calling the function
613    silc_client_free_channel_private_keys. The pointers in the array may be
614    used to delete the specific key by giving the pointer as argument to the
615    function silc_client_del_channel_private_key. */
616
617 SilcChannelPrivateKey *
618 silc_client_list_channel_private_keys(SilcClient client,
619                                       SilcClientConnection conn,
620                                       SilcChannelEntry channel,
621                                       uint32 *key_count)
622 {
623   SilcChannelPrivateKey *keys = NULL, entry;
624   uint32 count = 0;
625
626   if (!channel->private_keys)
627     return NULL;
628
629   silc_dlist_start(channel->private_keys);
630   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
631     keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
632     keys[count] = entry;
633     count++;
634   }
635
636   if (key_count)
637     *key_count = count;
638
639   return keys;
640 }
641
642 /* Frees the SilcChannelPrivateKey array. */
643
644 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
645                                            uint32 key_count)
646 {
647   silc_free(keys);
648 }
649
650 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the 
651    channel indicated by the `channel'. NULL if client is not joined on
652    the channel. */
653
654 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
655                                        SilcClientEntry client_entry)
656 {
657   SilcChannelUser chu;
658
659   if (silc_hash_table_find(channel->user_list, client_entry, NULL, 
660                            (void *)&chu))
661     return chu;
662
663   return NULL;
664 }