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