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