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