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