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 "silcincludes.h"
26 #include "silcclient.h"
27 #include "client_internal.h"
29 /* Sends packet to the `channel'. Packet to channel is always encrypted
30 differently from "normal" packets. SILC header of the packet is
31 encrypted with the next receiver's key and the rest of the packet is
32 encrypted with the channel specific key. Padding and HMAC is computed
33 with the next receiver's key. The `data' is the channel message. If
34 the `force_send' is TRUE then the packet is sent immediately. */
36 void silc_client_send_channel_message(SilcClient client,
37 SilcClientConnection conn,
38 SilcChannelEntry channel,
39 SilcChannelPrivateKey key,
40 SilcMessageFlags flags,
46 SilcSocketConnection sock = conn->sock;
48 SilcPacketContext packetdata;
49 const SilcBufferStruct packet;
52 unsigned char *id_string;
57 SILC_LOG_DEBUG(("Sending packet to channel"));
59 chu = silc_client_on_channel(channel, conn->local_entry);
61 SILC_LOG_ERROR(("Cannot send message to channel we are not joined"));
65 /* Check if it is allowed to send messages to this channel by us. */
66 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && !chu->mode)
68 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
69 chu->mode & SILC_CHANNEL_UMODE_CHANOP &&
70 !(chu->mode & SILC_CHANNEL_UMODE_CHANFO))
72 if (chu->mode & SILC_CHANNEL_UMODE_QUIET)
75 /* Take the key to be used */
76 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
78 /* Use key application specified */
81 } else if (channel->curr_key) {
82 /* Use current private key */
83 cipher = channel->curr_key->cipher;
84 hmac = channel->curr_key->hmac;
85 } else if (!channel->curr_key && channel->private_keys) {
86 /* Use just some private key since we don't know what to use
87 and private keys are set. */
88 silc_dlist_start(channel->private_keys);
89 key = silc_dlist_get(channel->private_keys);
93 /* Use this key as current private key */
94 channel->curr_key = key;
96 /* Use normal channel key generated by the server */
97 cipher = channel->channel_key;
101 /* Use normal channel key generated by the server */
102 cipher = channel->channel_key;
103 hmac = channel->hmac;
106 if (!cipher || !hmac)
109 block_len = silc_cipher_get_block_len(cipher);
112 iv_len = silc_cipher_get_block_len(cipher);
113 if (channel->iv[0] == '\0')
114 for (i = 0; i < iv_len; i++) channel->iv[i] =
115 silc_rng_get_byte(client->rng);
117 silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
119 /* Encode the channel payload. This also encrypts the message payload. */
120 payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len,
121 channel->iv, cipher, hmac,
124 /* Get data used in packet header encryption, keys and stuff. */
125 cipher = conn->internal->send_key;
126 hmac = conn->internal->hmac_send;
127 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
129 /* Set the packet context pointers. The destination ID is always
130 the Channel ID of the channel. Server and router will handle the
131 distribution of the packet. */
132 data = payload->data;
133 data_len = payload->len;
134 packetdata.flags = 0;
135 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
136 packetdata.src_id = conn->local_id_data;
137 packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
138 packetdata.src_id_type = SILC_ID_CLIENT;
139 packetdata.dst_id = id_string;
140 packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
141 packetdata.dst_id_type = SILC_ID_CHANNEL;
142 data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
143 packetdata.src_id_len +
144 packetdata.dst_id_len);
145 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
146 packetdata.src_id_len + packetdata.dst_id_len;
147 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
148 packetdata.src_id_len +
149 packetdata.dst_id_len), block_len);
151 /* Create the outgoing packet */
152 if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
153 data, data_len, (const SilcBuffer)&packet)) {
154 SILC_LOG_ERROR(("Error assembling packet"));
158 /* Encrypt the header and padding of the packet. This is encrypted
159 with normal session key shared with our server. */
160 silc_packet_encrypt(cipher, hmac, conn->internal->psn_send++,
161 (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN +
162 packetdata.src_id_len + packetdata.dst_id_len +
165 SILC_LOG_HEXDUMP(("Packet to channel, len %d", packet.len),
166 packet.data, packet.len);
168 /* Now actually send the packet */
169 silc_client_packet_send_real(client, sock, force_send);
172 silc_buffer_free(payload);
173 silc_free(id_string);
177 SilcChannelMessagePayload payload;
178 SilcChannelID *channel_id;
179 } *SilcChannelClientResolve;
181 static void silc_client_channel_message_cb(SilcClient client,
182 SilcClientConnection conn,
183 SilcClientEntry *clients,
184 SilcUInt32 clients_count,
187 SilcChannelClientResolve res = (SilcChannelClientResolve)context;
189 if (clients_count == 1) {
190 SilcChannelEntry channel;
191 unsigned char *message;
192 SilcUInt32 message_len;
194 channel = silc_client_get_channel_by_id(client, conn, res->channel_id);
198 /* If this client is not on channel, add it there since it clearly
200 if (!silc_client_on_channel(channel, clients[0])) {
201 SilcChannelUser chu = silc_calloc(1, sizeof(*chu));
202 chu->client = clients[0];
203 chu->channel = channel;
204 silc_hash_table_add(channel->user_list, clients[0], chu);
205 silc_hash_table_add(clients[0]->channels, channel, chu);
208 message = silc_channel_message_get_data(res->payload, &message_len);
210 /* Pass the message to application */
211 client->internal->ops->channel_message(
212 client, conn, clients[0], channel,
213 silc_channel_message_get_flags(res->payload),
214 message, message_len);
218 silc_channel_message_payload_free(res->payload);
219 silc_free(res->channel_id);
223 /* Process received message to a channel (or from a channel, really). This
224 decrypts the channel message with channel specific key and parses the
225 channel payload. Finally it displays the message on the screen. */
227 void silc_client_channel_message(SilcClient client,
228 SilcSocketConnection sock,
229 SilcPacketContext *packet)
231 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
232 SilcBuffer buffer = packet->buffer;
233 SilcChannelMessagePayload payload = NULL;
234 SilcChannelID *id = NULL;
235 SilcChannelEntry channel;
236 SilcClientEntry client_entry;
237 SilcClientID *client_id = NULL;
238 unsigned char *message;
239 SilcUInt32 message_len;
241 SILC_LOG_DEBUG(("Start"));
244 if (packet->dst_id_type != SILC_ID_CHANNEL)
247 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
251 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
255 /* Find the channel entry from channels on this connection */
256 channel = silc_client_get_channel_by_id(client, conn, id);
260 /* If there is no channel private key then just decrypt the message
261 with the channel key. If private keys are set then just go through
262 all private keys and check what decrypts correctly. */
263 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
264 /* Parse the channel message payload. This also decrypts the payload */
265 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
266 channel->channel_key,
269 /* If decryption failed and we have just performed channel key rekey
270 we will use the old key in decryption. If that fails too then we
271 cannot do more and will drop the packet. */
273 if (!channel->old_channel_key) {
277 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
278 channel->old_channel_key,
284 } else if (channel->private_keys) {
285 SilcChannelPrivateKey entry;
287 silc_dlist_start(channel->private_keys);
288 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
289 /* Parse the channel message payload. This also decrypts the payload */
290 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
296 if (entry == SILC_LIST_END)
302 /* Find client entry */
303 client_entry = silc_client_get_client_by_id(client, conn, client_id);
304 if (!client_entry || !client_entry->nickname ||
305 !silc_client_on_channel(channel, client_entry)) {
306 /* Resolve the client info */
307 SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
308 res->payload = payload;
309 res->channel_id = id;
310 silc_client_get_client_by_id_resolve(client, conn, client_id, NULL,
311 silc_client_channel_message_cb,
318 message = silc_channel_message_get_data(payload, &message_len);
320 /* Pass the message to application */
321 client->internal->ops->channel_message(
322 client, conn, client_entry, channel,
323 silc_channel_message_get_flags(payload),
324 message, message_len);
328 silc_free(client_id);
330 silc_channel_message_payload_free(payload);
333 /* Timeout callback that is called after a short period of time after the
334 new channel key has been created. This removes the old channel key all
337 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
339 SilcChannelEntry channel = (SilcChannelEntry)context;
341 if (channel->old_channel_key)
342 silc_cipher_free(channel->old_channel_key);
343 if (channel->old_hmac)
344 silc_hmac_free(channel->old_hmac);
345 channel->old_channel_key = NULL;
346 channel->old_hmac = NULL;
347 channel->rekey_task = NULL;
350 /* Saves channel key from encoded `key_payload'. This is used when we
351 receive Channel Key Payload and when we are processing JOIN command
354 void silc_client_save_channel_key(SilcClient client,
355 SilcClientConnection conn,
356 SilcBuffer key_payload,
357 SilcChannelEntry channel)
359 unsigned char *id_string, *key, *cipher, *hmac, hash[32];
362 SilcChannelKeyPayload payload;
364 payload = silc_channel_key_payload_parse(key_payload->data,
369 id_string = silc_channel_key_get_id(payload, &tmp_len);
371 silc_channel_key_payload_free(payload);
375 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
377 silc_channel_key_payload_free(payload);
383 channel = silc_client_get_channel_by_id(client, conn, id);
388 hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
391 /* Save the old key for a short period of time so that we can decrypt
392 channel message even after the rekey if some client would be sending
393 messages with the old key after the rekey. */
394 if (channel->old_channel_key)
395 silc_cipher_free(channel->old_channel_key);
396 if (channel->old_hmac)
397 silc_hmac_free(channel->old_hmac);
398 if (channel->rekey_task)
399 silc_schedule_task_del(client->schedule, channel->rekey_task);
400 channel->old_channel_key = channel->channel_key;
401 channel->old_hmac = channel->hmac;
402 channel->rekey_task =
403 silc_schedule_task_add(client->schedule, 0,
404 silc_client_save_channel_key_rekey, channel,
405 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
407 /* Free the old channel key data */
408 silc_free(channel->key);
411 key = silc_channel_key_get_key(payload, &tmp_len);
412 cipher = silc_channel_key_get_cipher(payload, NULL);
413 channel->key_len = tmp_len * 8;
414 channel->key = silc_memdup(key, tmp_len);
416 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
417 client->internal->ops->say(
419 SILC_CLIENT_MESSAGE_AUDIT,
420 "Cannot talk to channel: unsupported cipher %s",
425 /* Set the cipher key */
426 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
428 /* Generate HMAC key from the channel key data and set it */
429 silc_hmac_alloc(hmac, NULL, &channel->hmac);
430 silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
431 silc_hmac_set_key(channel->hmac, hash,
432 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
433 memset(hash, 0, sizeof(hash));
437 silc_channel_key_payload_free(payload);
440 /* Processes received key for channel. The received key will be used
441 to protect the traffic on the channel for now on. Client must receive
442 the key to the channel before talking on the channel is possible.
443 This is the key that server has generated, this is not the channel
444 private key, it is entirely local setting. */
446 void silc_client_receive_channel_key(SilcClient client,
447 SilcSocketConnection sock,
450 SILC_LOG_DEBUG(("Received key for channel"));
453 silc_client_save_channel_key(client, sock->user_data, packet, NULL);
456 /* Adds private key for channel. This may be set only if the channel's mode
457 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
458 mode is not set. When channel has private key then the messages are
459 encrypted using that key. All clients on the channel must also know the
460 key in order to decrypt the messages. However, it is possible to have
461 several private keys per one channel. In this case only some of the
462 clients on the channel may know the one key and only some the other key.
464 If `cipher' and/or `hmac' is NULL then default values will be used
465 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
467 The private key for channel is optional. If it is not set then the
468 channel messages are encrypted using the channel key generated by the
469 server. However, setting the private key (or keys) for the channel
470 significantly adds security. If more than one key is set the library
471 will automatically try all keys at the message decryption phase. Note:
472 setting many keys slows down the decryption phase as all keys has to
473 be tried in order to find the correct decryption key. However, setting
474 a few keys does not have big impact to the decryption performace.
476 NOTE: that this is entirely local setting. The key set using this function
477 is not sent to the network at any phase.
479 NOTE: If the key material was originated by the SKE protocol (using
480 silc_client_send_key_agreement) then the `key' MUST be the
481 key->send_enc_key as this is dictated by the SILC protocol. However,
482 currently it is not expected that the SKE key material would be used
483 as channel private key. However, this API allows it. */
485 int silc_client_add_channel_private_key(SilcClient client,
486 SilcClientConnection conn,
487 SilcChannelEntry channel,
494 SilcChannelPrivateKey entry;
495 unsigned char hash[32];
496 SilcSKEKeyMaterial *keymat;
498 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
502 cipher = SILC_DEFAULT_CIPHER;
504 hmac = SILC_DEFAULT_HMAC;
506 if (!silc_cipher_is_supported(cipher))
509 if (!silc_hmac_is_supported(hmac))
512 /* Produce the key material */
513 keymat = silc_calloc(1, sizeof(*keymat));
514 if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
515 client->md5hash, keymat)
516 != SILC_SKE_STATUS_OK)
519 /* Remove the current key, if it exists. */
520 if (channel->channel_key) {
521 silc_cipher_free(channel->channel_key);
522 memset(channel->key, 0, channel->key_len / 8);
523 silc_free(channel->key);
524 channel->channel_key = NULL;
526 channel->key_len = 0;
529 silc_hmac_free(channel->hmac);
530 channel->hmac = NULL;
533 if (!channel->private_keys)
534 channel->private_keys = silc_dlist_init();
537 entry = silc_calloc(1, sizeof(*entry));
538 entry->name = name ? strdup(name) : NULL;
539 entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
540 entry->key_len = keymat->enc_key_len / 8;
542 /* Allocate the cipher and set the key*/
543 silc_cipher_alloc(cipher, &entry->cipher);
544 silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
546 /* Generate HMAC key from the channel key data and set it */
547 silc_hmac_alloc(hmac, NULL, &entry->hmac);
548 silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key,
549 entry->key_len, hash);
550 silc_hmac_set_key(entry->hmac, hash,
551 silc_hash_len(silc_hmac_get_hash(entry->hmac)));
552 memset(hash, 0, sizeof(hash));
554 /* Add to the private keys list */
555 silc_dlist_add(channel->private_keys, entry);
557 if (!channel->curr_key)
558 channel->curr_key = entry;
560 /* Free the key material */
561 silc_ske_free_key_material(keymat);
566 /* Removes all private keys from the `channel'. The old channel key is used
567 after calling this to protect the channel messages. Returns FALSE on
568 on error, TRUE otherwise. */
570 int silc_client_del_channel_private_keys(SilcClient client,
571 SilcClientConnection conn,
572 SilcChannelEntry channel)
574 SilcChannelPrivateKey entry;
576 if (!channel->private_keys)
579 silc_dlist_start(channel->private_keys);
580 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
581 silc_dlist_del(channel->private_keys, entry);
582 memset(entry->key, 0, entry->key_len);
583 silc_free(entry->key);
584 silc_free(entry->name);
585 silc_cipher_free(entry->cipher);
586 silc_hmac_free(entry->hmac);
590 channel->curr_key = NULL;
592 silc_dlist_uninit(channel->private_keys);
593 channel->private_keys = NULL;
598 /* Removes and frees private key `key' from the channel `channel'. The `key'
599 is retrieved by calling the function silc_client_list_channel_private_keys.
600 The key is not used after this. If the key was last private key then the
601 old channel key is used hereafter to protect the channel messages. This
602 returns FALSE on error, TRUE otherwise. */
604 int silc_client_del_channel_private_key(SilcClient client,
605 SilcClientConnection conn,
606 SilcChannelEntry channel,
607 SilcChannelPrivateKey key)
609 SilcChannelPrivateKey entry;
611 if (!channel->private_keys)
614 silc_dlist_start(channel->private_keys);
615 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
617 if (channel->curr_key == entry)
618 channel->curr_key = NULL;
620 silc_dlist_del(channel->private_keys, entry);
621 memset(entry->key, 0, entry->key_len);
622 silc_free(entry->key);
623 silc_free(entry->name);
624 silc_cipher_free(entry->cipher);
625 silc_hmac_free(entry->hmac);
628 if (silc_dlist_count(channel->private_keys) == 0) {
629 silc_dlist_uninit(channel->private_keys);
630 channel->private_keys = NULL;
640 /* Returns array (pointers) of private keys associated to the `channel'.
641 The caller must free the array by calling the function
642 silc_client_free_channel_private_keys. The pointers in the array may be
643 used to delete the specific key by giving the pointer as argument to the
644 function silc_client_del_channel_private_key. */
646 SilcChannelPrivateKey *
647 silc_client_list_channel_private_keys(SilcClient client,
648 SilcClientConnection conn,
649 SilcChannelEntry channel,
650 SilcUInt32 *key_count)
652 SilcChannelPrivateKey *keys = NULL, entry;
653 SilcUInt32 count = 0;
655 if (!channel->private_keys)
658 silc_dlist_start(channel->private_keys);
659 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
660 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
671 /* Frees the SilcChannelPrivateKey array. */
673 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
674 SilcUInt32 key_count)
679 /* Sets the `key' to be used as current channel private key on the
680 `channel'. Packet sent after calling this function will be secured
683 void silc_client_current_channel_private_key(SilcClient client,
684 SilcClientConnection conn,
685 SilcChannelEntry channel,
686 SilcChannelPrivateKey key)
688 channel->curr_key = key;
691 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the
692 channel indicated by the `channel'. NULL if client is not joined on
695 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
696 SilcClientEntry client_entry)
700 if (silc_hash_table_find(channel->user_list, client_entry, NULL,