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
53   SILC_LOG_DEBUG(("Sending packet to channel"));
54
55   /* Take the key to be used */
56   if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
57     if (key) {
58       /* Use key application specified */
59       cipher = key->cipher;
60       hmac = key->hmac;
61     } else if (channel->curr_key) {
62       /* Use current private key */
63       cipher = channel->curr_key->cipher;
64       hmac = channel->curr_key->hmac;
65     } else if (!channel->curr_key && channel->private_keys) {
66       /* Use just some private key since we don't know what to use 
67          and private keys are set. */
68       silc_dlist_start(channel->private_keys);
69       key = silc_dlist_get(channel->private_keys);
70       cipher = key->cipher;
71       hmac = key->hmac;
72       
73       /* Use this key as current private key */
74       channel->curr_key = key;
75     } else {
76       /* Use normal channel key generated by the server */
77       cipher = channel->channel_key;
78       hmac = channel->hmac;
79     }
80   } else {
81     /* Use normal channel key generated by the server */
82     cipher = channel->channel_key;
83     hmac = channel->hmac;
84   }
85
86   if (!cipher || !hmac)
87     return;
88
89   /* Generate IV */
90   iv_len = silc_cipher_get_block_len(cipher);
91   if (channel->iv[0] == '\0')
92     for (i = 0; i < iv_len; i++) channel->iv[i] = 
93                                    silc_rng_get_byte(client->rng);
94   else
95     silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
96
97   /* Encode the channel payload. This also encrypts the message payload. */
98   payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len, 
99                                                 channel->iv, cipher, hmac);
100
101   /* Get data used in packet header encryption, keys and stuff. */
102   cipher = conn->send_key;
103   hmac = conn->hmac_send;
104   id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
105
106   /* Set the packet context pointers. The destination ID is always
107      the Channel ID of the channel. Server and router will handle the
108      distribution of the packet. */
109   packetdata.flags = 0;
110   packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
111   packetdata.src_id = conn->local_id_data;
112   packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
113   packetdata.src_id_type = SILC_ID_CLIENT;
114   packetdata.dst_id = id_string;
115   packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
116   packetdata.dst_id_type = SILC_ID_CHANNEL;
117   packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN + 
118     packetdata.src_id_len + packetdata.dst_id_len;
119   packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
120                                           packetdata.src_id_len +
121                                           packetdata.dst_id_len));
122
123   /* Prepare outgoing data buffer for packet sending */
124   silc_packet_send_prepare(sock, 
125                            SILC_PACKET_HEADER_LEN +
126                            packetdata.src_id_len + 
127                            packetdata.dst_id_len,
128                            packetdata.padlen,
129                            payload->len);
130
131   packetdata.buffer = sock->outbuf;
132
133   /* Put the channel message payload to the outgoing data buffer */
134   silc_buffer_put(sock->outbuf, payload->data, payload->len);
135
136   /* Create the outgoing packet */
137   silc_packet_assemble(&packetdata);
138
139   /* Encrypt the header and padding of the packet. This is encrypted 
140      with normal session key shared with our server. */
141   silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN + 
142                       packetdata.src_id_len + packetdata.dst_id_len +
143                       packetdata.padlen);
144
145   SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
146                    sock->outbuf->data, sock->outbuf->len);
147
148   /* Now actually send the packet */
149   silc_client_packet_send_real(client, sock, force_send, FALSE);
150   silc_buffer_free(payload);
151   silc_free(id_string);
152 }
153
154 static void silc_client_channel_message_cb(SilcClient client,
155                                            SilcClientConnection conn,
156                                            SilcClientEntry *clients,
157                                            uint32 clients_count,
158                                            void *context)
159 {
160   SilcPacketContext *packet = (SilcPacketContext *)context;
161
162   if (clients)
163     silc_client_channel_message(client, conn->sock, packet);
164   silc_packet_context_free(packet);
165 }
166
167 /* Process received message to a channel (or from a channel, really). This
168    decrypts the channel message with channel specific key and parses the
169    channel payload. Finally it displays the message on the screen. */
170
171 void silc_client_channel_message(SilcClient client, 
172                                  SilcSocketConnection sock, 
173                                  SilcPacketContext *packet)
174 {
175   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
176   SilcBuffer buffer = packet->buffer;
177   SilcChannelMessagePayload payload = NULL;
178   SilcChannelID *id = NULL;
179   SilcChannelEntry channel;
180   SilcChannelUser chu;
181   SilcIDCacheEntry id_cache = NULL;
182   SilcClientID *client_id = NULL;
183   bool found = FALSE;
184   unsigned char *message;
185
186   SILC_LOG_DEBUG(("Start"));
187
188   /* Sanity checks */
189   if (packet->dst_id_type != SILC_ID_CHANNEL)
190     goto out;
191
192   client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
193                              SILC_ID_CLIENT);
194   if (!client_id)
195     goto out;
196   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
197   if (!id)
198     goto out;
199
200   /* Find the channel entry from channels on this connection */
201   if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id, &id_cache))
202     goto out;
203
204   channel = (SilcChannelEntry)id_cache->context;
205
206   /* If there is no channel private key then just decrypt the message 
207      with the channel key. If private keys are set then just go through
208      all private keys and check what decrypts correctly. */
209   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
210     /* Parse the channel message payload. This also decrypts the payload */
211     payload = silc_channel_message_payload_parse(buffer, channel->channel_key,
212                                                  channel->hmac);
213     if (!payload)
214       goto out;
215   } else if (channel->private_keys) {
216     SilcChannelPrivateKey entry;
217
218     silc_dlist_start(channel->private_keys);
219     while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
220       /* Parse the channel message payload. This also decrypts the payload */
221       payload = silc_channel_message_payload_parse(buffer, entry->cipher,
222                                                    entry->hmac);
223       if (payload)
224         break;
225     }
226     if (entry == SILC_LIST_END)
227       goto out;
228   } else {
229     goto out;
230   }
231
232   /* Find client entry */
233   silc_list_start(channel->clients);
234   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
235     if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id)) {
236       found = TRUE;
237       break;
238     }
239   }
240
241   if (!found) {
242     /* Resolve the client info */
243     silc_client_get_client_by_id_resolve(client, conn, client_id,
244                                          silc_client_channel_message_cb,
245                                          silc_packet_context_dup(packet));
246     goto out;
247   }
248
249   message = silc_channel_message_get_data(payload, NULL);
250
251   /* Pass the message to application */
252   client->ops->channel_message(client, conn, chu->client, channel,
253                                silc_channel_message_get_flags(payload),
254                                message);
255
256  out:
257   if (id)
258     silc_free(id);
259   if (client_id)
260     silc_free(client_id);
261   if (payload)
262     silc_channel_message_payload_free(payload);
263 }
264
265 /* Saves channel key from encoded `key_payload'. This is used when we
266    receive Channel Key Payload and when we are processing JOIN command 
267    reply. */
268
269 void silc_client_save_channel_key(SilcClientConnection conn,
270                                   SilcBuffer key_payload, 
271                                   SilcChannelEntry channel)
272 {
273   unsigned char *id_string, *key, *cipher, hash[32];
274   uint32 tmp_len;
275   SilcChannelID *id;
276   SilcIDCacheEntry id_cache = NULL;
277   SilcChannelKeyPayload payload;
278
279   payload = silc_channel_key_payload_parse(key_payload);
280   if (!payload)
281     return;
282
283   id_string = silc_channel_key_get_id(payload, &tmp_len);
284   if (!id_string) {
285     silc_channel_key_payload_free(payload);
286     return;
287   }
288
289   id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
290   if (!id) {
291     silc_channel_key_payload_free(payload);
292     return;
293   }
294
295   /* Find channel. */
296   if (!channel) {
297     if (!silc_idcache_find_by_id_one(conn->channel_cache, 
298                                      (void *)id, &id_cache))
299       goto out;
300     
301     /* Get channel entry */
302     channel = (SilcChannelEntry)id_cache->context;
303   }
304
305   /* Save the key */
306   key = silc_channel_key_get_key(payload, &tmp_len);
307   cipher = silc_channel_key_get_cipher(payload, NULL);
308   channel->key_len = tmp_len * 8;
309   channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
310   memcpy(channel->key, key, tmp_len);
311
312   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
313     conn->client->ops->say(conn->client, conn,
314                      "Cannot talk to channel: unsupported cipher %s", cipher);
315     goto out;
316   }
317
318   /* Set the cipher key */
319   silc_cipher_set_key(channel->channel_key, key, channel->key_len);
320
321   /* Generate HMAC key from the channel key data and set it */
322   if (!channel->hmac)
323     silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
324   silc_hash_make(channel->hmac->hash, key, tmp_len, hash);
325   silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
326   memset(hash, 0, sizeof(hash));
327
328  out:
329   silc_free(id);
330   silc_channel_key_payload_free(payload);
331 }
332
333 /* Processes received key for channel. The received key will be used
334    to protect the traffic on the channel for now on. Client must receive
335    the key to the channel before talking on the channel is possible. 
336    This is the key that server has generated, this is not the channel
337    private key, it is entirely local setting. */
338
339 void silc_client_receive_channel_key(SilcClient client,
340                                      SilcSocketConnection sock,
341                                      SilcBuffer packet)
342 {
343   SILC_LOG_DEBUG(("Received key for channel"));
344
345   /* Save the key */
346   silc_client_save_channel_key(sock->user_data, packet, NULL);
347 }
348
349 /* Adds private key for channel. This may be set only if the channel's mode
350    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
351    mode is not set. When channel has private key then the messages are
352    encrypted using that key. All clients on the channel must also know the
353    key in order to decrypt the messages. However, it is possible to have
354    several private keys per one channel. In this case only some of the
355    clients on the channel may know the one key and only some the other key.
356
357    If `cipher' and/or `hmac' is NULL then default values will be used 
358    (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
359
360    The private key for channel is optional. If it is not set then the
361    channel messages are encrypted using the channel key generated by the
362    server. However, setting the private key (or keys) for the channel 
363    significantly adds security. If more than one key is set the library
364    will automatically try all keys at the message decryption phase. Note:
365    setting many keys slows down the decryption phase as all keys has to
366    be tried in order to find the correct decryption key. However, setting
367    a few keys does not have big impact to the decryption performace. 
368
369    NOTE: that this is entirely local setting. The key set using this function
370    is not sent to the network at any phase.
371
372    NOTE: If the key material was originated by the SKE protocol (using
373    silc_client_send_key_agreement) then the `key' MUST be the
374    key->send_enc_key as this is dictated by the SILC protocol. However,
375    currently it is not expected that the SKE key material would be used
376    as channel private key. However, this API allows it. */
377
378 int silc_client_add_channel_private_key(SilcClient client,
379                                         SilcClientConnection conn,
380                                         SilcChannelEntry channel,
381                                         char *cipher,
382                                         char *hmac,
383                                         unsigned char *key,
384                                         uint32 key_len)
385 {
386   SilcChannelPrivateKey entry;
387   unsigned char hash[32];
388   SilcSKEKeyMaterial *keymat;
389
390   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
391     return FALSE;
392
393   if (!cipher)
394     cipher = "aes-256-cbc";
395   if (!hmac)
396     hmac = "hmac-sha1-96";
397
398   if (!silc_cipher_is_supported(cipher))
399     return FALSE;
400
401   if (!silc_hmac_is_supported(hmac))
402     return FALSE;
403
404   /* Produce the key material */
405   keymat = silc_calloc(1, sizeof(*keymat));
406   if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16, 
407                                          client->md5hash, keymat) 
408       != SILC_SKE_STATUS_OK)
409     return FALSE;
410
411   /* Remove the current key, if it exists. */
412   if (channel->channel_key) {
413     silc_cipher_free(channel->channel_key);
414     memset(channel->key, 0, channel->key_len / 8);
415     silc_free(channel->key);
416     channel->channel_key = NULL;
417     channel->key = NULL;
418     channel->key_len = 0;
419   }
420   if (channel->hmac) {
421     silc_hmac_free(channel->hmac);
422     channel->hmac = NULL;
423   }
424
425   if (!channel->private_keys)
426     channel->private_keys = silc_dlist_init();
427
428   /* Save the key */
429   entry = silc_calloc(1, sizeof(*entry));
430   entry->key = silc_calloc(keymat->enc_key_len / 8, sizeof(*entry->key));
431   memcpy(entry->key, keymat->send_enc_key, keymat->enc_key_len / 8);
432   entry->key_len = keymat->enc_key_len / 8;
433
434   /* Allocate the cipher and set the key*/
435   silc_cipher_alloc(cipher, &entry->cipher);
436   silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
437
438   /* Generate HMAC key from the channel key data and set it */
439   silc_hmac_alloc(hmac, NULL, &entry->hmac);
440   silc_hash_make(entry->hmac->hash, entry->key, entry->key_len, hash);
441   silc_hmac_set_key(entry->hmac, hash, silc_hash_len(entry->hmac->hash));
442   memset(hash, 0, sizeof(hash));
443
444   /* Add to the private keys list */
445   silc_dlist_add(channel->private_keys, entry);
446
447   if (!channel->curr_key)
448     channel->curr_key = entry;
449
450   /* Free the key material */
451   silc_ske_free_key_material(keymat);
452
453   return TRUE;
454 }
455
456 /* Removes all private keys from the `channel'. The old channel key is used
457    after calling this to protect the channel messages. Returns FALSE on
458    on error, TRUE otherwise. */
459
460 int silc_client_del_channel_private_keys(SilcClient client,
461                                          SilcClientConnection conn,
462                                          SilcChannelEntry channel)
463 {
464   SilcChannelPrivateKey entry;
465
466   if (!channel->private_keys)
467     return FALSE;
468
469   silc_dlist_start(channel->private_keys);
470   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
471     silc_dlist_del(channel->private_keys, entry);
472     memset(entry->key, 0, entry->key_len);
473     silc_free(entry->key);
474     silc_cipher_free(entry->cipher);
475     silc_hmac_free(entry->hmac);
476     silc_free(entry);
477   }
478
479   channel->curr_key = NULL;
480
481   silc_dlist_uninit(channel->private_keys);
482   channel->private_keys = NULL;
483
484   return TRUE;
485 }
486
487 /* Removes and frees private key `key' from the channel `channel'. The `key'
488    is retrieved by calling the function silc_client_list_channel_private_keys.
489    The key is not used after this. If the key was last private key then the
490    old channel key is used hereafter to protect the channel messages. This
491    returns FALSE on error, TRUE otherwise. */
492
493 int silc_client_del_channel_private_key(SilcClient client,
494                                         SilcClientConnection conn,
495                                         SilcChannelEntry channel,
496                                         SilcChannelPrivateKey key)
497 {
498   SilcChannelPrivateKey entry;
499
500   if (!channel->private_keys)
501     return FALSE;
502
503   silc_dlist_start(channel->private_keys);
504   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
505     if (entry == key) {
506       if (channel->curr_key == entry)
507         channel->curr_key = NULL;
508
509       silc_dlist_del(channel->private_keys, entry);
510       memset(entry->key, 0, entry->key_len);
511       silc_free(entry->key);
512       silc_cipher_free(entry->cipher);
513       silc_hmac_free(entry->hmac);
514       silc_free(entry);
515
516       if (silc_dlist_count(channel->private_keys) == 0) {
517         silc_dlist_uninit(channel->private_keys);
518         channel->private_keys = NULL;
519       }
520
521       return TRUE;
522     }
523   }
524
525   return FALSE;
526 }
527
528 /* Returns array (pointers) of private keys associated to the `channel'.
529    The caller must free the array by calling the function
530    silc_client_free_channel_private_keys. The pointers in the array may be
531    used to delete the specific key by giving the pointer as argument to the
532    function silc_client_del_channel_private_key. */
533
534 SilcChannelPrivateKey *
535 silc_client_list_channel_private_keys(SilcClient client,
536                                       SilcClientConnection conn,
537                                       SilcChannelEntry channel,
538                                       uint32 *key_count)
539 {
540   SilcChannelPrivateKey *keys = NULL, entry;
541   uint32 count = 0;
542
543   if (!channel->private_keys)
544     return NULL;
545
546   silc_dlist_start(channel->private_keys);
547   while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
548     keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
549     keys[count] = entry;
550     count++;
551   }
552
553   if (key_count)
554     *key_count = count;
555
556   return keys;
557 }
558
559 /* Frees the SilcChannelPrivateKey array. */
560
561 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
562                                            uint32 key_count)
563 {
564   silc_free(keys);
565 }