5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 /* This file includes channel message sending and receiving routines,
21 channel key receiving and setting, and channel private key handling
24 #include "silcincludes.h"
25 #include "silcclient.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,
38 SilcChannelPrivateKey key,
39 SilcMessageFlags flags,
44 SilcSocketConnection sock;
46 SilcPacketContext packetdata;
47 const SilcBufferStruct packet;
50 unsigned char *id_string;
54 assert(client && conn && channel);
56 SILC_LOG_DEBUG(("Sending packet to channel"));
58 chu = silc_client_on_channel(channel, conn->local_entry);
60 SILC_LOG_ERROR(("Cannot send message to channel we are not joined"));
64 /* Check if it is allowed to send messages to this channel by us. */
65 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && !chu->mode)
67 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
68 chu->mode & SILC_CHANNEL_UMODE_CHANOP &&
69 !(chu->mode & SILC_CHANNEL_UMODE_CHANFO))
71 if (chu->mode & SILC_CHANNEL_UMODE_QUIET)
74 /* Take the key to be used */
75 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
77 /* Use key application specified */
80 } else if (channel->curr_key) {
81 /* Use current private key */
82 cipher = channel->curr_key->cipher;
83 hmac = channel->curr_key->hmac;
84 } else if (!channel->curr_key && channel->private_keys) {
85 /* Use just some private key since we don't know what to use
86 and private keys are set. */
87 silc_dlist_start(channel->private_keys);
88 key = silc_dlist_get(channel->private_keys);
92 /* Use this key as current private key */
93 channel->curr_key = key;
95 /* Use normal channel key generated by the server */
96 cipher = channel->channel_key;
100 /* Use normal channel key generated by the server */
101 cipher = channel->channel_key;
102 hmac = channel->hmac;
105 if (!cipher || !hmac)
108 block_len = silc_cipher_get_block_len(cipher);
110 /* Encode the message payload. This also encrypts the message payload. */
111 payload = silc_message_payload_encode(flags, data, data_len, TRUE, FALSE,
112 cipher, hmac, client->rng, NULL,
113 client->private_key, client->sha1hash);
115 /* Get data used in packet header encryption, keys and stuff. */
116 cipher = conn->internal->send_key;
117 hmac = conn->internal->hmac_send;
118 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
120 /* Set the packet context pointers. The destination ID is always
121 the Channel ID of the channel. Server and router will handle the
122 distribution of the packet. */
123 data = payload->data;
124 data_len = payload->len;
125 packetdata.flags = 0;
126 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
127 packetdata.src_id = conn->local_id_data;
128 packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
129 packetdata.src_id_type = SILC_ID_CLIENT;
130 packetdata.dst_id = id_string;
131 packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
132 packetdata.dst_id_type = SILC_ID_CHANNEL;
133 data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
134 packetdata.src_id_len +
135 packetdata.dst_id_len);
136 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
137 packetdata.src_id_len + packetdata.dst_id_len;
138 SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
139 packetdata.src_id_len +
140 packetdata.dst_id_len), block_len, packetdata.padlen);
142 /* Create the outgoing packet */
143 if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
144 data, data_len, (const SilcBuffer)&packet)) {
145 SILC_LOG_ERROR(("Error assembling packet"));
149 /* Encrypt the header and padding of the packet. This is encrypted
150 with normal session key shared with our server. */
151 silc_packet_encrypt(cipher, hmac, conn->internal->psn_send++,
152 (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN +
153 packetdata.src_id_len + packetdata.dst_id_len +
156 SILC_LOG_HEXDUMP(("Packet to channel, len %d", packet.len),
157 packet.data, packet.len);
159 /* Now actually send the packet */
160 silc_client_packet_send_real(client, sock, force_send);
162 /* Check for mandatory rekey */
163 if (conn->internal->psn_send == SILC_CLIENT_REKEY_THRESHOLD)
164 silc_schedule_task_add(client->schedule, sock->sock,
165 silc_client_rekey_callback, sock, 0, 1,
166 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
169 silc_buffer_free(payload);
170 silc_free(id_string);
174 SilcMessagePayload payload;
175 SilcChannelID *channel_id;
176 } *SilcChannelClientResolve;
178 static void silc_client_channel_message_cb(SilcClient client,
179 SilcClientConnection conn,
180 SilcClientEntry *clients,
181 SilcUInt32 clients_count,
184 SilcChannelClientResolve res = (SilcChannelClientResolve)context;
186 if (clients_count == 1) {
187 SilcChannelEntry channel;
188 unsigned char *message;
189 SilcUInt32 message_len;
191 channel = silc_client_get_channel_by_id(client, conn, res->channel_id);
195 /* If this client is not on channel, add it there since it clearly
197 if (!silc_client_on_channel(channel, clients[0])) {
198 SilcChannelUser chu = silc_calloc(1, sizeof(*chu));
199 chu->client = clients[0];
200 chu->channel = channel;
201 silc_hash_table_add(channel->user_list, clients[0], chu);
202 silc_hash_table_add(clients[0]->channels, channel, chu);
205 message = silc_message_get_data(res->payload, &message_len);
207 /* Pass the message to application */
208 client->internal->ops->channel_message(
209 client, conn, clients[0], channel, res->payload,
210 silc_message_get_flags(res->payload),
211 message, message_len);
215 silc_message_payload_free(res->payload);
216 silc_free(res->channel_id);
220 /* Process received message to a channel (or from a channel, really). This
221 decrypts the channel message with channel specific key and parses the
222 message payload. Finally it displays the message on the screen. */
224 void silc_client_channel_message(SilcClient client,
225 SilcSocketConnection sock,
226 SilcPacketContext *packet)
228 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
229 SilcBuffer buffer = packet->buffer;
230 SilcMessagePayload payload = NULL;
231 SilcChannelID *id = NULL;
232 SilcChannelEntry channel;
233 SilcClientEntry client_entry;
234 SilcClientID *client_id = NULL;
235 unsigned char *message;
236 SilcUInt32 message_len;
238 SILC_LOG_DEBUG(("Start"));
241 if (packet->dst_id_type != SILC_ID_CHANNEL)
244 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
248 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
252 /* Find the channel entry from channels on this connection */
253 channel = silc_client_get_channel_by_id(client, conn, id);
257 /* If there is no channel private key then just decrypt the message
258 with the channel key. If private keys are set then just go through
259 all private keys and check what decrypts correctly. */
260 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
261 /* Parse the channel message payload. This also decrypts the payload */
262 payload = silc_message_payload_parse(buffer->data, buffer->len, FALSE,
263 FALSE, channel->channel_key,
266 /* If decryption failed and we have just performed channel key rekey
267 we will use the old key in decryption. If that fails too then we
268 cannot do more and will drop the packet. */
270 if (!channel->old_channel_key) {
274 payload = silc_message_payload_parse(buffer->data, buffer->len,
276 channel->old_channel_key,
282 } else if (channel->private_keys) {
283 SilcChannelPrivateKey entry;
285 silc_dlist_start(channel->private_keys);
286 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
287 /* Parse the message payload. This also decrypts the payload */
288 payload = silc_message_payload_parse(buffer->data, buffer->len,
290 entry->cipher, entry->hmac);
294 if (entry == SILC_LIST_END)
300 /* Find client entry */
301 client_entry = silc_client_get_client_by_id(client, conn, client_id);
302 if (!client_entry || !client_entry->nickname ||
303 !silc_client_on_channel(channel, client_entry)) {
304 /* Resolve the client info */
305 SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
306 res->payload = payload;
307 res->channel_id = id;
308 silc_client_get_client_by_id_resolve(client, conn, client_id, NULL,
309 silc_client_channel_message_cb,
316 message = silc_message_get_data(payload, &message_len);
318 /* Pass the message to application */
319 client->internal->ops->channel_message(
320 client, conn, client_entry, channel, payload,
321 silc_message_get_flags(payload),
322 message, message_len);
326 silc_free(client_id);
328 silc_message_payload_free(payload);
331 /* Timeout callback that is called after a short period of time after the
332 new channel key has been created. This removes the old channel key all
335 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
337 SilcChannelEntry channel = (SilcChannelEntry)context;
339 if (channel->old_channel_key)
340 silc_cipher_free(channel->old_channel_key);
341 if (channel->old_hmac)
342 silc_hmac_free(channel->old_hmac);
343 channel->old_channel_key = NULL;
344 channel->old_hmac = NULL;
345 channel->rekey_task = NULL;
348 /* Saves channel key from encoded `key_payload'. This is used when we
349 receive Channel Key Payload and when we are processing JOIN command
352 void silc_client_save_channel_key(SilcClient client,
353 SilcClientConnection conn,
354 SilcBuffer key_payload,
355 SilcChannelEntry channel)
357 unsigned char *id_string, *key, *cipher, *hmac, hash[32];
360 SilcChannelKeyPayload payload;
362 payload = silc_channel_key_payload_parse(key_payload->data,
367 id_string = silc_channel_key_get_id(payload, &tmp_len);
369 silc_channel_key_payload_free(payload);
373 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
375 silc_channel_key_payload_free(payload);
381 channel = silc_client_get_channel_by_id(client, conn, id);
386 hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
389 /* Save the old key for a short period of time so that we can decrypt
390 channel message even after the rekey if some client would be sending
391 messages with the old key after the rekey. */
392 if (channel->old_channel_key)
393 silc_cipher_free(channel->old_channel_key);
394 if (channel->old_hmac)
395 silc_hmac_free(channel->old_hmac);
396 if (channel->rekey_task)
397 silc_schedule_task_del(client->schedule, channel->rekey_task);
398 channel->old_channel_key = channel->channel_key;
399 channel->old_hmac = channel->hmac;
400 channel->rekey_task =
401 silc_schedule_task_add(client->schedule, 0,
402 silc_client_save_channel_key_rekey, channel,
403 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
405 /* Free the old channel key data */
406 silc_free(channel->key);
409 key = silc_channel_key_get_key(payload, &tmp_len);
410 cipher = silc_channel_key_get_cipher(payload, NULL);
411 channel->key_len = tmp_len * 8;
412 channel->key = silc_memdup(key, tmp_len);
414 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
415 client->internal->ops->say(
417 SILC_CLIENT_MESSAGE_AUDIT,
418 "Cannot talk to channel: unsupported cipher %s",
423 /* Set the cipher key */
424 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
426 /* Generate HMAC key from the channel key data and set it */
427 silc_hmac_alloc(hmac, NULL, &channel->hmac);
428 silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
429 silc_hmac_set_key(channel->hmac, hash,
430 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
431 memset(hash, 0, sizeof(hash));
435 silc_channel_key_payload_free(payload);
438 /* Processes received key for channel. The received key will be used
439 to protect the traffic on the channel for now on. Client must receive
440 the key to the channel before talking on the channel is possible.
441 This is the key that server has generated, this is not the channel
442 private key, it is entirely local setting. */
444 void silc_client_receive_channel_key(SilcClient client,
445 SilcSocketConnection sock,
448 SILC_LOG_DEBUG(("Received key for channel"));
451 silc_client_save_channel_key(client, sock->user_data, packet, NULL);
454 /* Adds private key for channel. This may be set only if the channel's mode
455 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
456 mode is not set. When channel has private key then the messages are
457 encrypted using that key. All clients on the channel must also know the
458 key in order to decrypt the messages. However, it is possible to have
459 several private keys per one channel. In this case only some of the
460 clients on the channel may know the one key and only some the other key.
462 If `cipher' and/or `hmac' is NULL then default values will be used
463 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
465 The private key for channel is optional. If it is not set then the
466 channel messages are encrypted using the channel key generated by the
467 server. However, setting the private key (or keys) for the channel
468 significantly adds security. If more than one key is set the library
469 will automatically try all keys at the message decryption phase. Note:
470 setting many keys slows down the decryption phase as all keys has to
471 be tried in order to find the correct decryption key. However, setting
472 a few keys does not have big impact to the decryption performace.
474 NOTE: that this is entirely local setting. The key set using this function
475 is not sent to the network at any phase.
477 NOTE: If the key material was originated by the SKE protocol (using
478 silc_client_send_key_agreement) then the `key' MUST be the
479 key->send_enc_key as this is dictated by the SILC protocol. However,
480 currently it is not expected that the SKE key material would be used
481 as channel private key. However, this API allows it. */
483 bool silc_client_add_channel_private_key(SilcClient client,
484 SilcClientConnection conn,
485 SilcChannelEntry channel,
492 SilcChannelPrivateKey entry;
493 unsigned char hash[32];
494 SilcSKEKeyMaterial *keymat;
496 assert(client && channel);
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->sha1hash, 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 bool silc_client_del_channel_private_keys(SilcClient client,
571 SilcClientConnection conn,
572 SilcChannelEntry channel)
574 SilcChannelPrivateKey entry;
576 assert(client && channel);
578 if (!channel->private_keys)
581 silc_dlist_start(channel->private_keys);
582 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
583 silc_dlist_del(channel->private_keys, entry);
584 memset(entry->key, 0, entry->key_len);
585 silc_free(entry->key);
586 silc_free(entry->name);
587 silc_cipher_free(entry->cipher);
588 silc_hmac_free(entry->hmac);
592 channel->curr_key = NULL;
594 silc_dlist_uninit(channel->private_keys);
595 channel->private_keys = NULL;
600 /* Removes and frees private key `key' from the channel `channel'. The `key'
601 is retrieved by calling the function silc_client_list_channel_private_keys.
602 The key is not used after this. If the key was last private key then the
603 old channel key is used hereafter to protect the channel messages. This
604 returns FALSE on error, TRUE otherwise. */
606 bool silc_client_del_channel_private_key(SilcClient client,
607 SilcClientConnection conn,
608 SilcChannelEntry channel,
609 SilcChannelPrivateKey key)
611 SilcChannelPrivateKey entry;
613 assert(client && channel);
615 if (!channel->private_keys)
618 silc_dlist_start(channel->private_keys);
619 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
621 if (channel->curr_key == entry)
622 channel->curr_key = NULL;
624 silc_dlist_del(channel->private_keys, entry);
625 memset(entry->key, 0, entry->key_len);
626 silc_free(entry->key);
627 silc_free(entry->name);
628 silc_cipher_free(entry->cipher);
629 silc_hmac_free(entry->hmac);
632 if (silc_dlist_count(channel->private_keys) == 0) {
633 silc_dlist_uninit(channel->private_keys);
634 channel->private_keys = NULL;
644 /* Returns array (pointers) of private keys associated to the `channel'.
645 The caller must free the array by calling the function
646 silc_client_free_channel_private_keys. The pointers in the array may be
647 used to delete the specific key by giving the pointer as argument to the
648 function silc_client_del_channel_private_key. */
650 SilcChannelPrivateKey *
651 silc_client_list_channel_private_keys(SilcClient client,
652 SilcClientConnection conn,
653 SilcChannelEntry channel,
654 SilcUInt32 *key_count)
656 SilcChannelPrivateKey *keys = NULL, entry;
657 SilcUInt32 count = 0;
659 assert(client && channel);
661 if (!channel->private_keys)
664 silc_dlist_start(channel->private_keys);
665 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
666 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
677 /* Frees the SilcChannelPrivateKey array. */
679 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
680 SilcUInt32 key_count)
685 /* Sets the `key' to be used as current channel private key on the
686 `channel'. Packet sent after calling this function will be secured
689 void silc_client_current_channel_private_key(SilcClient client,
690 SilcClientConnection conn,
691 SilcChannelEntry channel,
692 SilcChannelPrivateKey key)
694 assert(client && channel);
695 channel->curr_key = key;
698 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the
699 channel indicated by the `channel'. NULL if client is not joined on
702 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
703 SilcClientEntry client_entry)
707 if (silc_hash_table_find(channel->user_list, client_entry, NULL,