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