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                                       unsigned char *data, 
39                                       unsigned int data_len, 
40                                       int force_send)
41 {
42   int i;
43   SilcSocketConnection sock = conn->sock;
44   SilcBuffer payload;
45   SilcPacketContext packetdata;
46   SilcCipher cipher;
47   SilcHmac hmac;
48   unsigned char *id_string;
49   unsigned int iv_len;
50
51   SILC_LOG_DEBUG(("Sending packet to channel"));
52
53   if (!channel || !channel->key || !channel->hmac) {
54     client->ops->say(client, conn, 
55                      "Cannot talk to channel: key does not exist");
56     return;
57   }
58
59   /* Generate IV */
60   iv_len = silc_cipher_get_block_len(channel->channel_key);
61   if (channel->iv[0] == '\0')
62     for (i = 0; i < iv_len; i++) channel->iv[i] = 
63                                    silc_rng_get_byte(client->rng);
64   else
65     silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
66
67   /* Encode the channel payload. This also encrypts the message payload. */
68   payload = silc_channel_payload_encode(data_len, data, iv_len, 
69                                         channel->iv, channel->channel_key,
70                                         channel->hmac, client->rng);
71
72   /* Get data used in packet header encryption, keys and stuff. */
73   cipher = conn->send_key;
74   hmac = conn->hmac;
75   id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
76
77   /* Set the packet context pointers. The destination ID is always
78      the Channel ID of the channel. Server and router will handle the
79      distribution of the packet. */
80   packetdata.flags = 0;
81   packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
82   packetdata.src_id = conn->local_id_data;
83   packetdata.src_id_len = SILC_ID_CLIENT_LEN;
84   packetdata.src_id_type = SILC_ID_CLIENT;
85   packetdata.dst_id = id_string;
86   packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
87   packetdata.dst_id_type = SILC_ID_CHANNEL;
88   packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN + 
89     packetdata.src_id_len + packetdata.dst_id_len;
90   packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
91                                           packetdata.src_id_len +
92                                           packetdata.dst_id_len));
93
94   /* Prepare outgoing data buffer for packet sending */
95   silc_packet_send_prepare(sock, 
96                            SILC_PACKET_HEADER_LEN +
97                            packetdata.src_id_len + 
98                            packetdata.dst_id_len,
99                            packetdata.padlen,
100                            payload->len);
101
102   packetdata.buffer = sock->outbuf;
103
104   /* Put the channel message payload to the outgoing data buffer */
105   silc_buffer_put(sock->outbuf, payload->data, payload->len);
106
107   /* Create the outgoing packet */
108   silc_packet_assemble(&packetdata);
109
110   /* Encrypt the header and padding of the packet. This is encrypted 
111      with normal session key shared with our server. */
112   silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN + 
113                       packetdata.src_id_len + packetdata.dst_id_len +
114                       packetdata.padlen);
115
116   SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
117                    sock->outbuf->data, sock->outbuf->len);
118
119   /* Now actually send the packet */
120   silc_client_packet_send_real(client, sock, force_send);
121   silc_buffer_free(payload);
122   silc_free(id_string);
123 }
124
125 /* Process received message to a channel (or from a channel, really). This
126    decrypts the channel message with channel specific key and parses the
127    channel payload. Finally it displays the message on the screen. */
128
129 void silc_client_channel_message(SilcClient client, 
130                                  SilcSocketConnection sock, 
131                                  SilcPacketContext *packet)
132 {
133   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
134   SilcBuffer buffer = packet->buffer;
135   SilcChannelPayload payload = NULL;
136   SilcChannelID *id = NULL;
137   SilcChannelEntry channel;
138   SilcChannelUser chu;
139   SilcIDCacheEntry id_cache = NULL;
140   SilcClientID *client_id = NULL;
141   int found = FALSE;
142   unsigned char *message;
143
144   SILC_LOG_DEBUG(("Start"));
145
146   /* Sanity checks */
147   if (packet->dst_id_type != SILC_ID_CHANNEL)
148     goto out;
149
150   client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
151                              SILC_ID_CLIENT);
152   if (!client_id)
153     goto out;
154   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
155   if (!id)
156     goto out;
157
158   /* Find the channel entry from channels on this connection */
159   if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
160                                    SILC_ID_CHANNEL, &id_cache))
161     goto out;
162
163   channel = (SilcChannelEntry)id_cache->context;
164
165   /* Parse the channel message payload. This also decrypts the payload */
166   payload = silc_channel_payload_parse(buffer, channel->channel_key,
167                                        channel->hmac);
168   if (!payload)
169     goto out;
170
171   message = silc_channel_get_data(payload, NULL);
172
173   /* Find client entry */
174   silc_list_start(channel->clients);
175   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
176     if (!SILC_ID_CLIENT_COMPARE(chu->client->id, client_id)) {
177       found = TRUE;
178       break;
179     }
180   }
181
182   /* Pass the message to application */
183   client->ops->channel_message(client, conn, found ? chu->client : NULL,
184                                channel, message);
185
186  out:
187   if (id)
188     silc_free(id);
189   if (client_id)
190     silc_free(client_id);
191   if (payload)
192     silc_channel_payload_free(payload);
193 }
194
195 /* Saves channel key from encoded `key_payload'. This is used when we
196    receive Channel Key Payload and when we are processing JOIN command 
197    reply. */
198
199 void silc_client_save_channel_key(SilcClientConnection conn,
200                                   SilcBuffer key_payload, 
201                                   SilcChannelEntry channel)
202 {
203   unsigned char *id_string, *key, *cipher, hash[32];
204   unsigned int tmp_len;
205   SilcChannelID *id;
206   SilcIDCacheEntry id_cache = NULL;
207   SilcChannelKeyPayload payload;
208
209   payload = silc_channel_key_payload_parse(key_payload);
210   if (!payload)
211     return;
212
213   id_string = silc_channel_key_get_id(payload, &tmp_len);
214   if (!id_string) {
215     silc_channel_key_payload_free(payload);
216     return;
217   }
218
219   id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
220   if (!id) {
221     silc_channel_key_payload_free(payload);
222     return;
223   }
224
225   /* Find channel. */
226   if (!channel) {
227     if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
228                                      SILC_ID_CHANNEL, &id_cache))
229       goto out;
230     
231     /* Get channel entry */
232     channel = (SilcChannelEntry)id_cache->context;
233   }
234
235   /* Save the key */
236   key = silc_channel_key_get_key(payload, &tmp_len);
237   cipher = silc_channel_key_get_cipher(payload, NULL);
238   channel->key_len = tmp_len * 8;
239   channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
240   memcpy(channel->key, key, tmp_len);
241
242   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
243     conn->client->ops->say(conn->client, conn,
244                      "Cannot talk to channel: unsupported cipher %s", cipher);
245     goto out;
246   }
247
248   /* Set the cipher key */
249   silc_cipher_set_key(channel->channel_key, key, channel->key_len);
250
251   /* Generate HMAC key from the channel key data and set it */
252   if (!channel->hmac)
253     silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
254   silc_hash_make(channel->hmac->hash, key, tmp_len, hash);
255   silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
256   memset(hash, 0, sizeof(hash));
257
258   /* Client is now joined to the channel */
259   channel->on_channel = TRUE;
260
261  out:
262   silc_free(id);
263   silc_channel_key_payload_free(payload);
264 }
265
266 /* Processes received key for channel. The received key will be used
267    to protect the traffic on the channel for now on. Client must receive
268    the key to the channel before talking on the channel is possible. 
269    This is the key that server has generated, this is not the channel
270    private key, it is entirely local setting. */
271
272 void silc_client_receive_channel_key(SilcClient client,
273                                      SilcSocketConnection sock,
274                                      SilcBuffer packet)
275 {
276   SILC_LOG_DEBUG(("Received key for channel"));
277
278   /* Save the key */
279   silc_client_save_channel_key(sock->user_data, packet, NULL);
280 }
281
282 /* Adds private key for channel. This may be set only if the channel's mode
283    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
284    mode is not set. When channel has private key then the messages are
285    encrypted using that key. All clients on the channel must also know the
286    key in order to decrypt the messages. However, it is possible to have
287    several private keys per one channel. In this case only some of the
288    clients on the channel may now the one key and only some the other key.
289
290    The private key for channel is optional. If it is not set then the
291    channel messages are encrypted using the channel key generated by the
292    server. However, setting the private key (or keys) for the channel 
293    significantly adds security. If more than one key is set the library
294    will automatically try all keys at the message decryption phase. Note:
295    setting many keys slows down the decryption phase as all keys has to
296    be tried in order to find the correct decryption key. However, setting
297    a few keys does not have big impact to the decryption performace. 
298
299    NOTE: that this is entirely local setting. The key set using this function
300    is not sent to the network at any phase.
301
302    NOTE: If the key material was originated by the SKE protocol (using
303    silc_client_send_key_agreement) then the `key' MUST be the
304    key->send_enc_key as this is dictated by the SILC protocol. However,
305    currently it is not expected that the SKE key material would be used
306    as channel private key. However, this API allows it. */
307
308 int silc_client_add_channel_private_key(SilcClient client,
309                                         SilcClientConnection conn,
310                                         SilcChannelEntry channel,
311                                         char *cipher,
312                                         unsigned char *key,
313                                         unsigned int key_len)
314 {
315
316   return TRUE;
317 }
318
319 /* Removes all private keys from the `channel'. The old channel key is used
320    after calling this to protect the channel messages. Returns FALSE on
321    on error, TRUE otherwise. */
322
323 int silc_client_del_channel_private_keys(SilcClient client,
324                                          SilcClientConnection conn,
325                                          SilcChannelEntry channel)
326 {
327
328   return TRUE;
329 }
330
331 /* Removes and frees private key `key' from the channel `channel'. The `key'
332    is retrieved by calling the function silc_client_list_channel_private_keys.
333    The key is not used after this. If the key was last private key then the
334    old channel key is used hereafter to protect the channel messages. This
335    returns FALSE on error, TRUE otherwise. */
336
337 int silc_client_del_channel_private_key(SilcClient client,
338                                         SilcClientConnection conn,
339                                         SilcChannelEntry channel,
340                                         SilcChannelPrivateKey key)
341 {
342
343   return TRUE;
344 }
345
346 /* Returns array (pointers) of private keys associated to the `channel'.
347    The caller must free the array by calling the function
348    silc_client_free_channel_private_keys. The pointers in the array may be
349    used to delete the specific key by giving the pointer as argument to the
350    function silc_client_del_channel_private_key. */
351
352 SilcChannelPrivateKey *
353 silc_client_list_channel_private_keys(SilcClient client,
354                                       SilcClientConnection conn,
355                                       SilcChannelEntry channel,
356                                       unsigned int *key_count)
357 {
358
359   return NULL;
360 }
361
362 /* Frees the SilcChannelPrivateKey array. */
363
364 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
365                                            unsigned int key_count)
366 {
367
368 }