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