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