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