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_memdup(key, tmp_len);
400
401   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
402     client->internal->ops->say(
403                            conn->client, conn, 
404                            SILC_CLIENT_MESSAGE_AUDIT,
405                            "Cannot talk to channel: unsupported cipher %s", 
406                            cipher);
407     goto out;
408   }
409
410   /* Set the cipher key */
411   silc_cipher_set_key(channel->channel_key, key, channel->key_len);
412
413   /* Generate HMAC key from the channel key data and set it */
414   silc_hmac_alloc(hmac, NULL, &channel->hmac);
415   silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
416   silc_hmac_set_key(channel->hmac, hash, 
417                     silc_hash_len(silc_hmac_get_hash(channel->hmac)));
418   memset(hash, 0, sizeof(hash));
419
420  out:
421   silc_free(id);
422   silc_channel_key_payload_free(payload);
423 }
424
425 /* Processes received key for channel. The received key will be used
426    to protect the traffic on the channel for now on. Client must receive
427    the key to the channel before talking on the channel is possible. 
428    This is the key that server has generated, this is not the channel
429    private key, it is entirely local setting. */
430
431 void silc_client_receive_channel_key(SilcClient client,
432                                      SilcSocketConnection sock,
433                                      SilcBuffer packet)
434 {
435   SILC_LOG_DEBUG(("Received key for channel"));
436
437   /* Save the key */
438   silc_client_save_channel_key(client, sock->user_data, packet, NULL);
439 }
440
441 /* Adds private key for channel. This may be set only if the channel's mode
442    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
443    mode is not set. When channel has private key then the messages are
444    encrypted using that key. All clients on the channel must also know the
445    key in order to decrypt the messages. However, it is possible to have
446    several private keys per one channel. In this case only some of the
447    clients on the channel may know the one key and only some the other key.
448
449    If `cipher' and/or `hmac' is NULL then default values will be used 
450    (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
451
452    The private key for channel is optional. If it is not set then the
453    channel messages are encrypted using the channel key generated by the
454    server. However, setting the private key (or keys) for the channel 
455    significantly adds security. If more than one key is set the library
456    will automatically try all keys at the message decryption phase. Note:
457    setting many keys slows down the decryption phase as all keys has to
458    be tried in order to find the correct decryption key. However, setting
459    a few keys does not have big impact to the decryption performace. 
460
461    NOTE: that this is entirely local setting. The key set using this function
462    is not sent to the network at any phase.
463
464    NOTE: If the key material was originated by the SKE protocol (using
465    silc_client_send_key_agreement) then the `key' MUST be the
466    key->send_enc_key as this is dictated by the SILC protocol. However,
467    currently it is not expected that the SKE key material would be used
468    as channel private key. However, this API allows it. */
469
470 int silc_client_add_channel_private_key(SilcClient client,
471                                         SilcClientConnection conn,
472                                         SilcChannelEntry channel,
473                                         char *cipher,
474                                         char *hmac,
475                                         unsigned char *key,
476                                         uint32 key_len)
477 {
478   SilcChannelPrivateKey entry;
479   unsigned char hash[32];
480   SilcSKEKeyMaterial *keymat;
481
482   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
483     return FALSE;
484
485   if (!cipher)
486     cipher = SILC_DEFAULT_CIPHER;
487   if (!hmac)
488     hmac = SILC_DEFAULT_HMAC;
489
490   if (!silc_cipher_is_supported(cipher))
491     return FALSE;
492
493   if (!silc_hmac_is_supported(hmac))
494     return FALSE;
495
496   /* Produce the key material */
497   keymat = silc_calloc(1, sizeof(*keymat));
498   if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16, 
499                                          client->internal->md5hash, keymat) 
500       != SILC_SKE_STATUS_OK)
501     return FALSE;
502
503   /* Remove the current key, if it exists. */
504   if (channel->channel_key) {
505     silc_cipher_free(channel->channel_key);
506     memset(channel->key, 0, channel->key_len / 8);
507     silc_free(channel->key);
508     channel->channel_key = NULL;
509     channel->key = NULL;
510     channel->key_len = 0;
511   }
512   if (channel->hmac) {
513     silc_hmac_free(channel->hmac);
514     channel->hmac = NULL;
515   }
516
517   if (!channel->private_keys)
518     channel->private_keys = silc_dlist_init();
519
520   /* Save the key */
521   entry = silc_calloc(1, sizeof(*entry));
522   entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
523   entry->key_len = keymat->enc_key_len / 8;
524
525   /* Allocate the cipher and set the key*/
526   silc_cipher_alloc(cipher, &entry->cipher);
527   silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
528
529   /* Generate HMAC key from the channel key data and set it */
530   silc_hmac_alloc(hmac, NULL, &entry->hmac);
531   silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key, 
532                  entry->key_len, hash);
533   silc_hmac_set_key(entry->hmac, hash, 
534                     silc_hash_len(silc_hmac_get_hash(entry->hmac)));
535   memset(hash, 0, sizeof(hash));
536
537   /* Add to the private keys list */
538   silc_dlist_add(channel->private_keys, entry);
539
540   if (!channel->curr_key)
541     channel->curr_key = entry;
542
543   /* Free the key material */
544   silc_ske_free_key_material(keymat);
545
546   return TRUE;
547 }
548
549 /* Removes all private keys from the `channel'. The old channel key is used
550    after calling this to protect the channel messages. Returns FALSE on
551    on error, TRUE otherwise. */
552
553 int silc_client_del_channel_private_keys(SilcClient client,
554                                          SilcClientConnection conn,
555                                          SilcChannelEntry channel)
556 {
557   SilcChannelPrivateKey entry;
558
559   if (!channel->private_keys)
560     return FALSE;
561
562   silc_dlist_start(channel->private_keys);
563   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
564     silc_dlist_del(channel->private_keys, entry);
565     memset(entry->key, 0, entry->key_len);
566     silc_free(entry->key);
567     silc_cipher_free(entry->cipher);
568     silc_hmac_free(entry->hmac);
569     silc_free(entry);
570   }
571
572   channel->curr_key = NULL;
573
574   silc_dlist_uninit(channel->private_keys);
575   channel->private_keys = NULL;
576
577   return TRUE;
578 }
579
580 /* Removes and frees private key `key' from the channel `channel'. The `key'
581    is retrieved by calling the function silc_client_list_channel_private_keys.
582    The key is not used after this. If the key was last private key then the
583    old channel key is used hereafter to protect the channel messages. This
584    returns FALSE on error, TRUE otherwise. */
585
586 int silc_client_del_channel_private_key(SilcClient client,
587                                         SilcClientConnection conn,
588                                         SilcChannelEntry channel,
589                                         SilcChannelPrivateKey key)
590 {
591   SilcChannelPrivateKey entry;
592
593   if (!channel->private_keys)
594     return FALSE;
595
596   silc_dlist_start(channel->private_keys);
597   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
598     if (entry == key) {
599       if (channel->curr_key == entry)
600         channel->curr_key = NULL;
601
602       silc_dlist_del(channel->private_keys, entry);
603       memset(entry->key, 0, entry->key_len);
604       silc_free(entry->key);
605       silc_cipher_free(entry->cipher);
606       silc_hmac_free(entry->hmac);
607       silc_free(entry);
608
609       if (silc_dlist_count(channel->private_keys) == 0) {
610         silc_dlist_uninit(channel->private_keys);
611         channel->private_keys = NULL;
612       }
613
614       return TRUE;
615     }
616   }
617
618   return FALSE;
619 }
620
621 /* Returns array (pointers) of private keys associated to the `channel'.
622    The caller must free the array by calling the function
623    silc_client_free_channel_private_keys. The pointers in the array may be
624    used to delete the specific key by giving the pointer as argument to the
625    function silc_client_del_channel_private_key. */
626
627 SilcChannelPrivateKey *
628 silc_client_list_channel_private_keys(SilcClient client,
629                                       SilcClientConnection conn,
630                                       SilcChannelEntry channel,
631                                       uint32 *key_count)
632 {
633   SilcChannelPrivateKey *keys = NULL, entry;
634   uint32 count = 0;
635
636   if (!channel->private_keys)
637     return NULL;
638
639   silc_dlist_start(channel->private_keys);
640   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
641     keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
642     keys[count] = entry;
643     count++;
644   }
645
646   if (key_count)
647     *key_count = count;
648
649   return keys;
650 }
651
652 /* Frees the SilcChannelPrivateKey array. */
653
654 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
655                                            uint32 key_count)
656 {
657   silc_free(keys);
658 }
659
660 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the 
661    channel indicated by the `channel'. NULL if client is not joined on
662    the channel. */
663
664 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
665                                        SilcClientEntry client_entry)
666 {
667   SilcChannelUser chu;
668
669   if (silc_hash_table_find(channel->user_list, client_entry, NULL, 
670                            (void *)&chu))
671     return chu;
672
673   return NULL;
674 }