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