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