5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
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.
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.
21 /* This file includes channel message sending and receiving routines,
22 channel key receiving and setting, and channel private key handling
25 #include "clientlibincludes.h"
26 #include "client_internal.h"
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. */
35 void silc_client_send_channel_message(SilcClient client,
36 SilcClientConnection conn,
37 SilcChannelEntry channel,
39 unsigned int data_len,
43 SilcSocketConnection sock = conn->sock;
45 SilcPacketContext packetdata;
48 unsigned char *id_string;
51 SILC_LOG_DEBUG(("Sending packet to channel"));
53 if (!channel || !channel->key || !channel->hmac) {
54 client->ops->say(client, conn,
55 "Cannot talk to channel: key does not exist");
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);
65 silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
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);
72 /* Get data used in packet header encryption, keys and stuff. */
73 cipher = conn->send_key;
75 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
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. */
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));
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,
102 packetdata.buffer = sock->outbuf;
104 /* Put the channel message payload to the outgoing data buffer */
105 silc_buffer_put(sock->outbuf, payload->data, payload->len);
107 /* Create the outgoing packet */
108 silc_packet_assemble(&packetdata);
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 +
116 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
117 sock->outbuf->data, sock->outbuf->len);
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);
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. */
129 void silc_client_channel_message(SilcClient client,
130 SilcSocketConnection sock,
131 SilcPacketContext *packet)
133 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
134 SilcBuffer buffer = packet->buffer;
135 SilcChannelPayload payload = NULL;
136 SilcChannelID *id = NULL;
137 SilcChannelEntry channel;
139 SilcIDCacheEntry id_cache = NULL;
140 SilcClientID *client_id = NULL;
142 unsigned char *message;
144 SILC_LOG_DEBUG(("Start"));
147 if (packet->dst_id_type != SILC_ID_CHANNEL)
150 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
154 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
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))
163 channel = (SilcChannelEntry)id_cache->context;
165 /* Parse the channel message payload. This also decrypts the payload */
166 payload = silc_channel_payload_parse(buffer, channel->channel_key,
171 message = silc_channel_get_data(payload, NULL);
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)) {
182 /* Pass the message to application */
183 client->ops->channel_message(client, conn, found ? chu->client : NULL,
190 silc_free(client_id);
192 silc_channel_payload_free(payload);
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
199 void silc_client_save_channel_key(SilcClientConnection conn,
200 SilcBuffer key_payload,
201 SilcChannelEntry channel)
203 unsigned char *id_string, *key, *cipher, hash[32];
204 unsigned int tmp_len;
206 SilcIDCacheEntry id_cache = NULL;
207 SilcChannelKeyPayload payload;
209 payload = silc_channel_key_payload_parse(key_payload);
213 id_string = silc_channel_key_get_id(payload, &tmp_len);
215 silc_channel_key_payload_free(payload);
219 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
221 silc_channel_key_payload_free(payload);
227 if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
228 SILC_ID_CHANNEL, &id_cache))
231 /* Get channel entry */
232 channel = (SilcChannelEntry)id_cache->context;
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);
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);
248 /* Set the cipher key */
249 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
251 /* Generate HMAC key from the channel key data and set it */
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));
258 /* Client is now joined to the channel */
259 channel->on_channel = TRUE;
263 silc_channel_key_payload_free(payload);
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. */
272 void silc_client_receive_channel_key(SilcClient client,
273 SilcSocketConnection sock,
276 SILC_LOG_DEBUG(("Received key for channel"));
279 silc_client_save_channel_key(sock->user_data, packet, NULL);
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.
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.
299 NOTE: that this is entirely local setting. The key set using this function
300 is not sent to the network at any phase.
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. */
308 int silc_client_add_channel_private_key(SilcClient client,
309 SilcClientConnection conn,
310 SilcChannelEntry channel,
313 unsigned int key_len)
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. */
323 int silc_client_del_channel_private_keys(SilcClient client,
324 SilcClientConnection conn,
325 SilcChannelEntry channel)
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. */
337 int silc_client_del_channel_private_key(SilcClient client,
338 SilcClientConnection conn,
339 SilcChannelEntry channel,
340 SilcChannelPrivateKey key)
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. */
352 SilcChannelPrivateKey *
353 silc_client_list_channel_private_keys(SilcClient client,
354 SilcClientConnection conn,
355 SilcChannelEntry channel,
356 unsigned int *key_count)
362 /* Frees the SilcChannelPrivateKey array. */
364 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
365 unsigned int key_count)