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                                       unsigned int 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   unsigned int iv_len;
52
53   SILC_LOG_DEBUG(("Sending packet to channel"));
54
55   if (!channel || !channel->hmac || 
56       (!channel->channel_key && !key && !channel->private_keys)) {
57     client->ops->say(client, conn, 
58                      "Cannot talk to channel: key does not exist");
59     return;
60   }
61
62   /* Take the key to be used */
63   if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
64     if (key) {
65       /* Use key application specified */
66       cipher = key->cipher;
67       hmac = key->hmac;
68     } else if (channel->curr_key) {
69       /* Use current private key */
70       cipher = channel->curr_key->cipher;
71       hmac = channel->curr_key->hmac;
72     } else if (!channel->curr_key && channel->private_keys) {
73       /* Use just some private key since we don't know what to use 
74          and private keys are set. */
75       silc_dlist_start(channel->private_keys);
76       key = silc_dlist_get(channel->private_keys);
77       cipher = key->cipher;
78       hmac = key->hmac;
79       
80       /* Use this key as current private key */
81       channel->curr_key = key;
82     } else {
83       /* Use normal channel key generated by the server */
84       cipher = channel->channel_key;
85       hmac = channel->hmac;
86     }
87   } else {
88     /* Use normal channel key generated by the server */
89     cipher = channel->channel_key;
90     hmac = channel->hmac;
91   }
92
93   /* Generate IV */
94   iv_len = silc_cipher_get_block_len(cipher);
95   if (channel->iv[0] == '\0')
96     for (i = 0; i < iv_len; i++) channel->iv[i] = 
97                                    silc_rng_get_byte(client->rng);
98   else
99     silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
100
101   /* Encode the channel payload. This also encrypts the message payload. */
102   payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len, 
103                                                 channel->iv, cipher, hmac);
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   SilcChannelMessagePayload 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_message_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_message_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_message_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, 
238                                silc_channel_message_get_flags(payload),
239                                message);
240
241  out:
242   if (id)
243     silc_free(id);
244   if (client_id)
245     silc_free(client_id);
246   if (payload)
247     silc_channel_message_payload_free(payload);
248 }
249
250 /* Saves channel key from encoded `key_payload'. This is used when we
251    receive Channel Key Payload and when we are processing JOIN command 
252    reply. */
253
254 void silc_client_save_channel_key(SilcClientConnection conn,
255                                   SilcBuffer key_payload, 
256                                   SilcChannelEntry channel)
257 {
258   unsigned char *id_string, *key, *cipher, hash[32];
259   unsigned int tmp_len;
260   SilcChannelID *id;
261   SilcIDCacheEntry id_cache = NULL;
262   SilcChannelKeyPayload payload;
263
264   payload = silc_channel_key_payload_parse(key_payload);
265   if (!payload)
266     return;
267
268   id_string = silc_channel_key_get_id(payload, &tmp_len);
269   if (!id_string) {
270     silc_channel_key_payload_free(payload);
271     return;
272   }
273
274   id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
275   if (!id) {
276     silc_channel_key_payload_free(payload);
277     return;
278   }
279
280   /* Find channel. */
281   if (!channel) {
282     if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
283                                      SILC_ID_CHANNEL, &id_cache))
284       goto out;
285     
286     /* Get channel entry */
287     channel = (SilcChannelEntry)id_cache->context;
288   }
289
290   /* Save the key */
291   key = silc_channel_key_get_key(payload, &tmp_len);
292   cipher = silc_channel_key_get_cipher(payload, NULL);
293   channel->key_len = tmp_len * 8;
294   channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
295   memcpy(channel->key, key, tmp_len);
296
297   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
298     conn->client->ops->say(conn->client, conn,
299                      "Cannot talk to channel: unsupported cipher %s", cipher);
300     goto out;
301   }
302
303   /* Set the cipher key */
304   silc_cipher_set_key(channel->channel_key, key, channel->key_len);
305
306   /* Generate HMAC key from the channel key data and set it */
307   if (!channel->hmac)
308     silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
309   silc_hash_make(channel->hmac->hash, key, tmp_len, hash);
310   silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
311   memset(hash, 0, sizeof(hash));
312
313   /* Client is now joined to the channel */
314   channel->on_channel = TRUE;
315
316  out:
317   silc_free(id);
318   silc_channel_key_payload_free(payload);
319 }
320
321 /* Processes received key for channel. The received key will be used
322    to protect the traffic on the channel for now on. Client must receive
323    the key to the channel before talking on the channel is possible. 
324    This is the key that server has generated, this is not the channel
325    private key, it is entirely local setting. */
326
327 void silc_client_receive_channel_key(SilcClient client,
328                                      SilcSocketConnection sock,
329                                      SilcBuffer packet)
330 {
331   SILC_LOG_DEBUG(("Received key for channel"));
332
333   /* Save the key */
334   silc_client_save_channel_key(sock->user_data, packet, NULL);
335 }
336
337 /* Adds private key for channel. This may be set only if the channel's mode
338    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
339    mode is not set. When channel has private key then the messages are
340    encrypted using that key. All clients on the channel must also know the
341    key in order to decrypt the messages. However, it is possible to have
342    several private keys per one channel. In this case only some of the
343    clients on the channel may know the one key and only some the other key.
344
345    if `cipher' and/or `hmac' is NULL then default values will be used 
346    (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
347
348    The private key for channel is optional. If it is not set then the
349    channel messages are encrypted using the channel key generated by the
350    server. However, setting the private key (or keys) for the channel 
351    significantly adds security. If more than one key is set the library
352    will automatically try all keys at the message decryption phase. Note:
353    setting many keys slows down the decryption phase as all keys has to
354    be tried in order to find the correct decryption key. However, setting
355    a few keys does not have big impact to the decryption performace. 
356
357    NOTE: that this is entirely local setting. The key set using this function
358    is not sent to the network at any phase.
359
360    NOTE: If the key material was originated by the SKE protocol (using
361    silc_client_send_key_agreement) then the `key' MUST be the
362    key->send_enc_key as this is dictated by the SILC protocol. However,
363    currently it is not expected that the SKE key material would be used
364    as channel private key. However, this API allows it. */
365
366 int silc_client_add_channel_private_key(SilcClient client,
367                                         SilcClientConnection conn,
368                                         SilcChannelEntry channel,
369                                         char *cipher,
370                                         char *hmac,
371                                         unsigned char *key,
372                                         unsigned int key_len)
373 {
374   SilcChannelPrivateKey entry;
375   unsigned char hash[32];
376
377   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
378     return FALSE;
379
380   if (!cipher)
381     cipher = "aes-256-cbc";
382   if (!hmac)
383     hmac = "hmac-sha1-96";
384
385   if (!silc_cipher_is_supported(cipher))
386     return FALSE;
387
388   if (!silc_hmac_is_supported(hmac))
389     return FALSE;
390
391   /* Remove the current key, if it exists. */
392   if (channel->channel_key) {
393     silc_cipher_free(channel->channel_key);
394     memset(channel->key, 0, channel->key_len / 8);
395     silc_free(channel->key);
396     channel->channel_key = NULL;
397     channel->key = NULL;
398     channel->key_len = 0;
399   }
400   if (channel->hmac)
401     silc_hmac_free(channel->hmac);
402
403   if (!channel->private_keys)
404     channel->private_keys = silc_dlist_init();
405
406   /* Save the key */
407   entry = silc_calloc(1, sizeof(*entry));
408   entry->key = silc_calloc(key_len, sizeof(*entry->key));
409   memcpy(entry->key, key, key_len);
410   entry->key_len = key_len;
411
412   /* Allocate the cipher and set the key*/
413   silc_cipher_alloc(cipher, &entry->cipher);
414   silc_cipher_set_key(entry->cipher, key, key_len * 8);
415
416   /* Generate HMAC key from the channel key data and set it */
417   silc_hmac_alloc(hmac, NULL, &entry->hmac);
418   silc_hash_make(entry->hmac->hash, key, key_len, hash);
419   silc_hmac_set_key(entry->hmac, hash, silc_hash_len(entry->hmac->hash));
420   memset(hash, 0, sizeof(hash));
421
422   /* Add to the private keys list */
423   silc_dlist_add(channel->private_keys, entry);
424
425   if (!channel->curr_key)
426     channel->curr_key = entry;
427
428   return TRUE;
429 }
430
431 /* Removes all private keys from the `channel'. The old channel key is used
432    after calling this to protect the channel messages. Returns FALSE on
433    on error, TRUE otherwise. */
434
435 int silc_client_del_channel_private_keys(SilcClient client,
436                                          SilcClientConnection conn,
437                                          SilcChannelEntry channel)
438 {
439   SilcChannelPrivateKey entry;
440
441   if (!channel->private_keys)
442     return FALSE;
443
444   silc_dlist_start(channel->private_keys);
445   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
446     silc_dlist_del(channel->private_keys, entry);
447     memset(entry->key, 0, entry->key_len);
448     silc_free(entry->key);
449     silc_cipher_free(entry->cipher);
450     silc_hmac_free(entry->hmac);
451     silc_free(entry);
452   }
453
454   channel->curr_key = NULL;
455
456   silc_dlist_uninit(channel->private_keys);
457   channel->private_keys = NULL;
458
459   return TRUE;
460 }
461
462 /* Removes and frees private key `key' from the channel `channel'. The `key'
463    is retrieved by calling the function silc_client_list_channel_private_keys.
464    The key is not used after this. If the key was last private key then the
465    old channel key is used hereafter to protect the channel messages. This
466    returns FALSE on error, TRUE otherwise. */
467
468 int silc_client_del_channel_private_key(SilcClient client,
469                                         SilcClientConnection conn,
470                                         SilcChannelEntry channel,
471                                         SilcChannelPrivateKey key)
472 {
473   SilcChannelPrivateKey entry;
474
475   if (!channel->private_keys)
476     return FALSE;
477
478   silc_dlist_start(channel->private_keys);
479   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
480     if (entry == key) {
481       if (channel->curr_key == entry)
482         channel->curr_key = NULL;
483
484       silc_dlist_del(channel->private_keys, entry);
485       memset(entry->key, 0, entry->key_len);
486       silc_free(entry->key);
487       silc_cipher_free(entry->cipher);
488       silc_hmac_free(entry->hmac);
489       silc_free(entry);
490
491       if (silc_dlist_count(channel->private_keys) == 0) {
492         silc_dlist_uninit(channel->private_keys);
493         channel->private_keys = NULL;
494       }
495
496       return TRUE;
497     }
498   }
499
500   return FALSE;
501 }
502
503 /* Returns array (pointers) of private keys associated to the `channel'.
504    The caller must free the array by calling the function
505    silc_client_free_channel_private_keys. The pointers in the array may be
506    used to delete the specific key by giving the pointer as argument to the
507    function silc_client_del_channel_private_key. */
508
509 SilcChannelPrivateKey *
510 silc_client_list_channel_private_keys(SilcClient client,
511                                       SilcClientConnection conn,
512                                       SilcChannelEntry channel,
513                                       unsigned int *key_count)
514 {
515   SilcChannelPrivateKey *keys = NULL, entry;
516   unsigned int count = 0;
517
518   if (!channel->private_keys)
519     return NULL;
520
521   silc_dlist_start(channel->private_keys);
522   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
523     keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
524     keys[count] = entry;
525     count++;
526   }
527
528   if (key_count)
529     *key_count = count;
530
531   return keys;
532 }
533
534 /* Frees the SilcChannelPrivateKey array. */
535
536 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
537                                            unsigned int key_count)
538 {
539   silc_free(keys);
540 }