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                                       unsigned char *data, 
40                                       unsigned int data_len, 
41                                       int force_send)
42 {
43   int i;
44   SilcSocketConnection sock = conn->sock;
45   SilcBuffer payload;
46   SilcPacketContext packetdata;
47   SilcCipher cipher;
48   SilcHmac hmac;
49   unsigned char *id_string;
50   unsigned int iv_len;
51
52   SILC_LOG_DEBUG(("Sending packet to channel"));
53
54   if (!channel || !channel->hmac || 
55       (!channel->channel_key && !key && !channel->private_keys)) {
56     client->ops->say(client, conn, 
57                      "Cannot talk to channel: key does not exist");
58     return;
59   }
60
61   /* Take the key to be used */
62   if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
63     if (key) {
64       /* Use key application specified */
65       cipher = key->cipher;
66       hmac = key->hmac;
67     } else if (channel->curr_key) {
68       /* Use current private key */
69       cipher = channel->curr_key->cipher;
70       hmac = channel->curr_key->hmac;
71     } else if (!channel->curr_key && channel->private_keys) {
72       /* Use just some private key since we don't know what to use 
73          and private keys are set. */
74       silc_dlist_start(channel->private_keys);
75       key = silc_dlist_get(channel->private_keys);
76       cipher = key->cipher;
77       hmac = key->hmac;
78       
79       /* Use this key as current private key */
80       channel->curr_key = key;
81     } else {
82       /* Use normal channel key generated by the server */
83       cipher = channel->channel_key;
84       hmac = channel->hmac;
85     }
86   } else {
87     /* Use normal channel key generated by the server */
88     cipher = channel->channel_key;
89     hmac = channel->hmac;
90   }
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(0, 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;
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_CLIENT_LEN;
116   packetdata.src_id_type = SILC_ID_CLIENT;
117   packetdata.dst_id = id_string;
118   packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
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));
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);
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, sock->outbuf, SILC_PACKET_HEADER_LEN + 
145                       packetdata.src_id_len + packetdata.dst_id_len +
146                       packetdata.padlen);
147
148   SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
149                    sock->outbuf->data, sock->outbuf->len);
150
151   /* Now actually send the packet */
152   silc_client_packet_send_real(client, sock, force_send);
153   silc_buffer_free(payload);
154   silc_free(id_string);
155 }
156
157 /* Process received message to a channel (or from a channel, really). This
158    decrypts the channel message with channel specific key and parses the
159    channel payload. Finally it displays the message on the screen. */
160
161 void silc_client_channel_message(SilcClient client, 
162                                  SilcSocketConnection sock, 
163                                  SilcPacketContext *packet)
164 {
165   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
166   SilcBuffer buffer = packet->buffer;
167   SilcChannelMessagePayload payload = NULL;
168   SilcChannelID *id = NULL;
169   SilcChannelEntry channel;
170   SilcChannelUser chu;
171   SilcIDCacheEntry id_cache = NULL;
172   SilcClientID *client_id = NULL;
173   int found = FALSE;
174   unsigned char *message;
175
176   SILC_LOG_DEBUG(("Start"));
177
178   /* Sanity checks */
179   if (packet->dst_id_type != SILC_ID_CHANNEL)
180     goto out;
181
182   client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
183                              SILC_ID_CLIENT);
184   if (!client_id)
185     goto out;
186   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
187   if (!id)
188     goto out;
189
190   /* Find the channel entry from channels on this connection */
191   if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
192                                    SILC_ID_CHANNEL, &id_cache))
193     goto out;
194
195   channel = (SilcChannelEntry)id_cache->context;
196
197   /* If there is no channel private key then just decrypt the message 
198      with the channel key. If private keys are set then just go through
199      all private keys and check what decrypts correctly. */
200   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
201     /* Parse the channel message payload. This also decrypts the payload */
202     payload = silc_channel_message_payload_parse(buffer, channel->channel_key,
203                                                  channel->hmac);
204     if (!payload)
205       goto out;
206   } else if (channel->private_keys) {
207     SilcChannelPrivateKey entry;
208
209     silc_dlist_start(channel->private_keys);
210     while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
211       /* Parse the channel message payload. This also decrypts the payload */
212       payload = silc_channel_message_payload_parse(buffer, entry->cipher,
213                                                    entry->hmac);
214       if (payload)
215         break;
216     }
217     if (entry == SILC_LIST_END)
218       goto out;
219   } else {
220     goto out;
221   }
222
223   message = silc_channel_message_get_data(payload, NULL);
224
225   /* Find client entry */
226   silc_list_start(channel->clients);
227   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
228     if (!SILC_ID_CLIENT_COMPARE(chu->client->id, client_id)) {
229       found = TRUE;
230       break;
231     }
232   }
233
234   /* Pass the message to application */
235   client->ops->channel_message(client, conn, found ? chu->client : NULL,
236                                channel, message);
237
238  out:
239   if (id)
240     silc_free(id);
241   if (client_id)
242     silc_free(client_id);
243   if (payload)
244     silc_channel_message_payload_free(payload);
245 }
246
247 /* Saves channel key from encoded `key_payload'. This is used when we
248    receive Channel Key Payload and when we are processing JOIN command 
249    reply. */
250
251 void silc_client_save_channel_key(SilcClientConnection conn,
252                                   SilcBuffer key_payload, 
253                                   SilcChannelEntry channel)
254 {
255   unsigned char *id_string, *key, *cipher, hash[32];
256   unsigned int tmp_len;
257   SilcChannelID *id;
258   SilcIDCacheEntry id_cache = NULL;
259   SilcChannelKeyPayload payload;
260
261   payload = silc_channel_key_payload_parse(key_payload);
262   if (!payload)
263     return;
264
265   id_string = silc_channel_key_get_id(payload, &tmp_len);
266   if (!id_string) {
267     silc_channel_key_payload_free(payload);
268     return;
269   }
270
271   id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
272   if (!id) {
273     silc_channel_key_payload_free(payload);
274     return;
275   }
276
277   /* Find channel. */
278   if (!channel) {
279     if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
280                                      SILC_ID_CHANNEL, &id_cache))
281       goto out;
282     
283     /* Get channel entry */
284     channel = (SilcChannelEntry)id_cache->context;
285   }
286
287   /* Save the key */
288   key = silc_channel_key_get_key(payload, &tmp_len);
289   cipher = silc_channel_key_get_cipher(payload, NULL);
290   channel->key_len = tmp_len * 8;
291   channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
292   memcpy(channel->key, key, tmp_len);
293
294   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
295     conn->client->ops->say(conn->client, conn,
296                      "Cannot talk to channel: unsupported cipher %s", cipher);
297     goto out;
298   }
299
300   /* Set the cipher key */
301   silc_cipher_set_key(channel->channel_key, key, channel->key_len);
302
303   /* Generate HMAC key from the channel key data and set it */
304   if (!channel->hmac)
305     silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
306   silc_hash_make(channel->hmac->hash, key, tmp_len, hash);
307   silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
308   memset(hash, 0, sizeof(hash));
309
310   /* Client is now joined to the channel */
311   channel->on_channel = TRUE;
312
313  out:
314   silc_free(id);
315   silc_channel_key_payload_free(payload);
316 }
317
318 /* Processes received key for channel. The received key will be used
319    to protect the traffic on the channel for now on. Client must receive
320    the key to the channel before talking on the channel is possible. 
321    This is the key that server has generated, this is not the channel
322    private key, it is entirely local setting. */
323
324 void silc_client_receive_channel_key(SilcClient client,
325                                      SilcSocketConnection sock,
326                                      SilcBuffer packet)
327 {
328   SILC_LOG_DEBUG(("Received key for channel"));
329
330   /* Save the key */
331   silc_client_save_channel_key(sock->user_data, packet, NULL);
332 }
333
334 /* Adds private key for channel. This may be set only if the channel's mode
335    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
336    mode is not set. When channel has private key then the messages are
337    encrypted using that key. All clients on the channel must also know the
338    key in order to decrypt the messages. However, it is possible to have
339    several private keys per one channel. In this case only some of the
340    clients on the channel may know the one key and only some the other key.
341
342    if `cipher' and/or `hmac' is NULL then default values will be used 
343    (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
344
345    The private key for channel is optional. If it is not set then the
346    channel messages are encrypted using the channel key generated by the
347    server. However, setting the private key (or keys) for the channel 
348    significantly adds security. If more than one key is set the library
349    will automatically try all keys at the message decryption phase. Note:
350    setting many keys slows down the decryption phase as all keys has to
351    be tried in order to find the correct decryption key. However, setting
352    a few keys does not have big impact to the decryption performace. 
353
354    NOTE: that this is entirely local setting. The key set using this function
355    is not sent to the network at any phase.
356
357    NOTE: If the key material was originated by the SKE protocol (using
358    silc_client_send_key_agreement) then the `key' MUST be the
359    key->send_enc_key as this is dictated by the SILC protocol. However,
360    currently it is not expected that the SKE key material would be used
361    as channel private key. However, this API allows it. */
362
363 int silc_client_add_channel_private_key(SilcClient client,
364                                         SilcClientConnection conn,
365                                         SilcChannelEntry channel,
366                                         char *cipher,
367                                         char *hmac,
368                                         unsigned char *key,
369                                         unsigned int key_len)
370 {
371   SilcChannelPrivateKey entry;
372   unsigned char hash[32];
373
374   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
375     return FALSE;
376
377   if (!cipher)
378     cipher = "aes-256-cbc";
379   if (!hmac)
380     hmac = "hmac-sha1-96";
381
382   if (!silc_cipher_is_supported(cipher))
383     return FALSE;
384
385   if (!silc_hmac_is_supported(hmac))
386     return FALSE;
387
388   /* Remove the current key, if it exists. */
389   if (channel->channel_key) {
390     silc_cipher_free(channel->channel_key);
391     memset(channel->key, 0, channel->key_len / 8);
392     silc_free(channel->key);
393     channel->channel_key = NULL;
394     channel->key = NULL;
395     channel->key_len = 0;
396   }
397   if (channel->hmac)
398     silc_hmac_free(channel->hmac);
399
400   if (!channel->private_keys)
401     channel->private_keys = silc_dlist_init();
402
403   /* Save the key */
404   entry = silc_calloc(1, sizeof(*entry));
405   entry->key = silc_calloc(key_len, sizeof(*entry->key));
406   memcpy(entry->key, key, key_len);
407   entry->key_len = key_len;
408
409   /* Allocate the cipher and set the key*/
410   silc_cipher_alloc(cipher, &entry->cipher);
411   silc_cipher_set_key(entry->cipher, key, key_len * 8);
412
413   /* Generate HMAC key from the channel key data and set it */
414   silc_hmac_alloc(hmac, NULL, &entry->hmac);
415   silc_hash_make(entry->hmac->hash, key, key_len, hash);
416   silc_hmac_set_key(entry->hmac, hash, silc_hash_len(entry->hmac->hash));
417   memset(hash, 0, sizeof(hash));
418
419   /* Add to the private keys list */
420   silc_dlist_add(channel->private_keys, entry);
421
422   if (!channel->curr_key)
423     channel->curr_key = entry;
424
425   return TRUE;
426 }
427
428 /* Removes all private keys from the `channel'. The old channel key is used
429    after calling this to protect the channel messages. Returns FALSE on
430    on error, TRUE otherwise. */
431
432 int silc_client_del_channel_private_keys(SilcClient client,
433                                          SilcClientConnection conn,
434                                          SilcChannelEntry channel)
435 {
436   SilcChannelPrivateKey entry;
437
438   if (!channel->private_keys)
439     return FALSE;
440
441   silc_dlist_start(channel->private_keys);
442   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
443     silc_dlist_del(channel->private_keys, entry);
444     memset(entry->key, 0, entry->key_len);
445     silc_free(entry->key);
446     silc_cipher_free(entry->cipher);
447     silc_hmac_free(entry->hmac);
448     silc_free(entry);
449   }
450
451   channel->curr_key = NULL;
452
453   silc_dlist_uninit(channel->private_keys);
454   channel->private_keys = NULL;
455
456   return TRUE;
457 }
458
459 /* Removes and frees private key `key' from the channel `channel'. The `key'
460    is retrieved by calling the function silc_client_list_channel_private_keys.
461    The key is not used after this. If the key was last private key then the
462    old channel key is used hereafter to protect the channel messages. This
463    returns FALSE on error, TRUE otherwise. */
464
465 int silc_client_del_channel_private_key(SilcClient client,
466                                         SilcClientConnection conn,
467                                         SilcChannelEntry channel,
468                                         SilcChannelPrivateKey key)
469 {
470   SilcChannelPrivateKey entry;
471
472   if (!channel->private_keys)
473     return FALSE;
474
475   silc_dlist_start(channel->private_keys);
476   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
477     if (entry == key) {
478       if (channel->curr_key == entry)
479         channel->curr_key = NULL;
480
481       silc_dlist_del(channel->private_keys, entry);
482       memset(entry->key, 0, entry->key_len);
483       silc_free(entry->key);
484       silc_cipher_free(entry->cipher);
485       silc_hmac_free(entry->hmac);
486       silc_free(entry);
487
488       if (silc_dlist_count(channel->private_keys) == 0) {
489         silc_dlist_uninit(channel->private_keys);
490         channel->private_keys = NULL;
491       }
492
493       return TRUE;
494     }
495   }
496
497   return FALSE;
498 }
499
500 /* Returns array (pointers) of private keys associated to the `channel'.
501    The caller must free the array by calling the function
502    silc_client_free_channel_private_keys. The pointers in the array may be
503    used to delete the specific key by giving the pointer as argument to the
504    function silc_client_del_channel_private_key. */
505
506 SilcChannelPrivateKey *
507 silc_client_list_channel_private_keys(SilcClient client,
508                                       SilcClientConnection conn,
509                                       SilcChannelEntry channel,
510                                       unsigned int *key_count)
511 {
512   SilcChannelPrivateKey *keys = NULL, entry;
513   unsigned int count = 0;
514
515   if (!channel->private_keys)
516     return NULL;
517
518   silc_dlist_start(channel->private_keys);
519   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
520     keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
521     keys[count] = entry;
522     count++;
523   }
524
525   if (key_count)
526     *key_count = count;
527
528   return keys;
529 }
530
531 /* Frees the SilcChannelPrivateKey array. */
532
533 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
534                                            unsigned int key_count)
535 {
536   silc_free(keys);
537 }