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                                       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);
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 ? (char *)silc_hmac_get_name(channel->hmac) : 
335           SILC_DEFAULT_HMAC);
336
337   /* Save the old key for a short period of time so that we can decrypt
338      channel message even after the rekey if some client would be sending
339      messages with the old key after the rekey. */
340   if (channel->old_channel_key)
341     silc_cipher_free(channel->old_channel_key);
342   if (channel->old_hmac)
343     silc_hmac_free(channel->old_hmac);
344   if (channel->rekey_task)
345     silc_schedule_task_del(conn->client->schedule, channel->rekey_task);
346   channel->old_channel_key = channel->channel_key;
347   channel->old_hmac = channel->hmac;
348   channel->rekey_task = 
349     silc_schedule_task_add(conn->client->schedule, 0,
350                            silc_client_save_channel_key_rekey, channel,
351                            10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
352
353   /* Free the old channel key data */
354   silc_free(channel->key);
355
356   /* Save the key */
357   key = silc_channel_key_get_key(payload, &tmp_len);
358   cipher = silc_channel_key_get_cipher(payload, NULL);
359   channel->key_len = tmp_len * 8;
360   channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
361   memcpy(channel->key, key, tmp_len);
362
363   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
364     conn->client->ops->say(conn->client, conn, SILC_CLIENT_MESSAGE_AUDIT,
365                            "Cannot talk to channel: unsupported cipher %s", 
366                            cipher);
367     goto out;
368   }
369
370   /* Set the cipher key */
371   silc_cipher_set_key(channel->channel_key, key, channel->key_len);
372
373   /* Generate HMAC key from the channel key data and set it */
374   silc_hmac_alloc(hmac, NULL, &channel->hmac);
375   silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
376   silc_hmac_set_key(channel->hmac, hash, 
377                     silc_hash_len(silc_hmac_get_hash(channel->hmac)));
378   memset(hash, 0, sizeof(hash));
379
380  out:
381   silc_free(id);
382   silc_channel_key_payload_free(payload);
383 }
384
385 /* Processes received key for channel. The received key will be used
386    to protect the traffic on the channel for now on. Client must receive
387    the key to the channel before talking on the channel is possible. 
388    This is the key that server has generated, this is not the channel
389    private key, it is entirely local setting. */
390
391 void silc_client_receive_channel_key(SilcClient client,
392                                      SilcSocketConnection sock,
393                                      SilcBuffer packet)
394 {
395   SILC_LOG_DEBUG(("Received key for channel"));
396
397   /* Save the key */
398   silc_client_save_channel_key(sock->user_data, packet, NULL);
399 }
400
401 /* Adds private key for channel. This may be set only if the channel's mode
402    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
403    mode is not set. When channel has private key then the messages are
404    encrypted using that key. All clients on the channel must also know the
405    key in order to decrypt the messages. However, it is possible to have
406    several private keys per one channel. In this case only some of the
407    clients on the channel may know the one key and only some the other key.
408
409    If `cipher' and/or `hmac' is NULL then default values will be used 
410    (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
411
412    The private key for channel is optional. If it is not set then the
413    channel messages are encrypted using the channel key generated by the
414    server. However, setting the private key (or keys) for the channel 
415    significantly adds security. If more than one key is set the library
416    will automatically try all keys at the message decryption phase. Note:
417    setting many keys slows down the decryption phase as all keys has to
418    be tried in order to find the correct decryption key. However, setting
419    a few keys does not have big impact to the decryption performace. 
420
421    NOTE: that this is entirely local setting. The key set using this function
422    is not sent to the network at any phase.
423
424    NOTE: If the key material was originated by the SKE protocol (using
425    silc_client_send_key_agreement) then the `key' MUST be the
426    key->send_enc_key as this is dictated by the SILC protocol. However,
427    currently it is not expected that the SKE key material would be used
428    as channel private key. However, this API allows it. */
429
430 int silc_client_add_channel_private_key(SilcClient client,
431                                         SilcClientConnection conn,
432                                         SilcChannelEntry channel,
433                                         char *cipher,
434                                         char *hmac,
435                                         unsigned char *key,
436                                         uint32 key_len)
437 {
438   SilcChannelPrivateKey entry;
439   unsigned char hash[32];
440   SilcSKEKeyMaterial *keymat;
441
442   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
443     return FALSE;
444
445   if (!cipher)
446     cipher = SILC_DEFAULT_CIPHER;
447   if (!hmac)
448     hmac = SILC_DEFAULT_HMAC;
449
450   if (!silc_cipher_is_supported(cipher))
451     return FALSE;
452
453   if (!silc_hmac_is_supported(hmac))
454     return FALSE;
455
456   /* Produce the key material */
457   keymat = silc_calloc(1, sizeof(*keymat));
458   if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16, 
459                                          client->md5hash, keymat) 
460       != SILC_SKE_STATUS_OK)
461     return FALSE;
462
463   /* Remove the current key, if it exists. */
464   if (channel->channel_key) {
465     silc_cipher_free(channel->channel_key);
466     memset(channel->key, 0, channel->key_len / 8);
467     silc_free(channel->key);
468     channel->channel_key = NULL;
469     channel->key = NULL;
470     channel->key_len = 0;
471   }
472   if (channel->hmac) {
473     silc_hmac_free(channel->hmac);
474     channel->hmac = NULL;
475   }
476
477   if (!channel->private_keys)
478     channel->private_keys = silc_dlist_init();
479
480   /* Save the key */
481   entry = silc_calloc(1, sizeof(*entry));
482   entry->key = silc_calloc(keymat->enc_key_len / 8, sizeof(*entry->key));
483   memcpy(entry->key, keymat->send_enc_key, keymat->enc_key_len / 8);
484   entry->key_len = keymat->enc_key_len / 8;
485
486   /* Allocate the cipher and set the key*/
487   silc_cipher_alloc(cipher, &entry->cipher);
488   silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
489
490   /* Generate HMAC key from the channel key data and set it */
491   silc_hmac_alloc(hmac, NULL, &entry->hmac);
492   silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key, 
493                  entry->key_len, hash);
494   silc_hmac_set_key(entry->hmac, hash, 
495                     silc_hash_len(silc_hmac_get_hash(entry->hmac)));
496   memset(hash, 0, sizeof(hash));
497
498   /* Add to the private keys list */
499   silc_dlist_add(channel->private_keys, entry);
500
501   if (!channel->curr_key)
502     channel->curr_key = entry;
503
504   /* Free the key material */
505   silc_ske_free_key_material(keymat);
506
507   return TRUE;
508 }
509
510 /* Removes all private keys from the `channel'. The old channel key is used
511    after calling this to protect the channel messages. Returns FALSE on
512    on error, TRUE otherwise. */
513
514 int silc_client_del_channel_private_keys(SilcClient client,
515                                          SilcClientConnection conn,
516                                          SilcChannelEntry channel)
517 {
518   SilcChannelPrivateKey entry;
519
520   if (!channel->private_keys)
521     return FALSE;
522
523   silc_dlist_start(channel->private_keys);
524   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
525     silc_dlist_del(channel->private_keys, entry);
526     memset(entry->key, 0, entry->key_len);
527     silc_free(entry->key);
528     silc_cipher_free(entry->cipher);
529     silc_hmac_free(entry->hmac);
530     silc_free(entry);
531   }
532
533   channel->curr_key = NULL;
534
535   silc_dlist_uninit(channel->private_keys);
536   channel->private_keys = NULL;
537
538   return TRUE;
539 }
540
541 /* Removes and frees private key `key' from the channel `channel'. The `key'
542    is retrieved by calling the function silc_client_list_channel_private_keys.
543    The key is not used after this. If the key was last private key then the
544    old channel key is used hereafter to protect the channel messages. This
545    returns FALSE on error, TRUE otherwise. */
546
547 int silc_client_del_channel_private_key(SilcClient client,
548                                         SilcClientConnection conn,
549                                         SilcChannelEntry channel,
550                                         SilcChannelPrivateKey key)
551 {
552   SilcChannelPrivateKey entry;
553
554   if (!channel->private_keys)
555     return FALSE;
556
557   silc_dlist_start(channel->private_keys);
558   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
559     if (entry == key) {
560       if (channel->curr_key == entry)
561         channel->curr_key = NULL;
562
563       silc_dlist_del(channel->private_keys, entry);
564       memset(entry->key, 0, entry->key_len);
565       silc_free(entry->key);
566       silc_cipher_free(entry->cipher);
567       silc_hmac_free(entry->hmac);
568       silc_free(entry);
569
570       if (silc_dlist_count(channel->private_keys) == 0) {
571         silc_dlist_uninit(channel->private_keys);
572         channel->private_keys = NULL;
573       }
574
575       return TRUE;
576     }
577   }
578
579   return FALSE;
580 }
581
582 /* Returns array (pointers) of private keys associated to the `channel'.
583    The caller must free the array by calling the function
584    silc_client_free_channel_private_keys. The pointers in the array may be
585    used to delete the specific key by giving the pointer as argument to the
586    function silc_client_del_channel_private_key. */
587
588 SilcChannelPrivateKey *
589 silc_client_list_channel_private_keys(SilcClient client,
590                                       SilcClientConnection conn,
591                                       SilcChannelEntry channel,
592                                       uint32 *key_count)
593 {
594   SilcChannelPrivateKey *keys = NULL, entry;
595   uint32 count = 0;
596
597   if (!channel->private_keys)
598     return NULL;
599
600   silc_dlist_start(channel->private_keys);
601   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
602     keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
603     keys[count] = entry;
604     count++;
605   }
606
607   if (key_count)
608     *key_count = count;
609
610   return keys;
611 }
612
613 /* Frees the SilcChannelPrivateKey array. */
614
615 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
616                                            uint32 key_count)
617 {
618   silc_free(keys);
619 }