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