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))
73 /* Take the key to be used */
74 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
76 /* Use key application specified */
79 } else if (channel->curr_key) {
80 /* Use current private key */
81 cipher = channel->curr_key->cipher;
82 hmac = channel->curr_key->hmac;
83 } else if (!channel->curr_key && channel->private_keys) {
84 /* Use just some private key since we don't know what to use
85 and private keys are set. */
86 silc_dlist_start(channel->private_keys);
87 key = silc_dlist_get(channel->private_keys);
91 /* Use this key as current private key */
92 channel->curr_key = key;
94 /* Use normal channel key generated by the server */
95 cipher = channel->channel_key;
99 /* Use normal channel key generated by the server */
100 cipher = channel->channel_key;
101 hmac = channel->hmac;
104 if (!cipher || !hmac)
107 block_len = silc_cipher_get_block_len(cipher);
110 iv_len = silc_cipher_get_block_len(cipher);
111 if (channel->iv[0] == '\0')
112 for (i = 0; i < iv_len; i++) channel->iv[i] =
113 silc_rng_get_byte(client->rng);
115 silc_hash_make(client->internal->md5hash, channel->iv, iv_len,
118 /* Encode the channel payload. This also encrypts the message payload. */
119 payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len,
120 channel->iv, cipher, hmac,
123 /* Get data used in packet header encryption, keys and stuff. */
124 cipher = conn->send_key;
125 hmac = conn->hmac_send;
126 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
128 /* Set the packet context pointers. The destination ID is always
129 the Channel ID of the channel. Server and router will handle the
130 distribution of the packet. */
131 data = payload->data;
132 data_len = payload->len;
133 packetdata.flags = 0;
134 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
135 packetdata.src_id = conn->local_id_data;
136 packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
137 packetdata.src_id_type = SILC_ID_CLIENT;
138 packetdata.dst_id = id_string;
139 packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
140 packetdata.dst_id_type = SILC_ID_CHANNEL;
141 data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
142 packetdata.src_id_len +
143 packetdata.dst_id_len);
144 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
145 packetdata.src_id_len + packetdata.dst_id_len;
146 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
147 packetdata.src_id_len +
148 packetdata.dst_id_len), block_len);
150 /* Create the outgoing packet */
151 if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
152 data, data_len, (const SilcBuffer)&packet)) {
153 SILC_LOG_ERROR(("Error assembling packet"));
157 /* Encrypt the header and padding of the packet. This is encrypted
158 with normal session key shared with our server. */
159 silc_packet_encrypt(cipher, hmac, conn->psn_send++,
160 (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN +
161 packetdata.src_id_len + packetdata.dst_id_len +
164 SILC_LOG_HEXDUMP(("Packet to channel, len %d", packet.len),
165 packet.data, packet.len);
167 /* Now actually send the packet */
168 silc_client_packet_send_real(client, sock, force_send);
171 silc_buffer_free(payload);
172 silc_free(id_string);
176 SilcChannelMessagePayload payload;
177 SilcChannelID *channel_id;
178 } *SilcChannelClientResolve;
180 static void silc_client_channel_message_cb(SilcClient client,
181 SilcClientConnection conn,
182 SilcClientEntry *clients,
183 SilcUInt32 clients_count,
186 SilcChannelClientResolve res = (SilcChannelClientResolve)context;
188 if (clients_count == 1) {
189 SilcChannelEntry channel;
190 unsigned char *message;
191 SilcUInt32 message_len;
193 channel = silc_client_get_channel_by_id(client, conn, res->channel_id);
197 /* If this client is not on channel, add it there since it clearly
199 if (!silc_client_on_channel(channel, clients[0])) {
200 SilcChannelUser chu = silc_calloc(1, sizeof(*chu));
201 chu->client = clients[0];
202 chu->channel = channel;
203 silc_hash_table_add(channel->user_list, clients[0], chu);
204 silc_hash_table_add(clients[0]->channels, channel, chu);
207 message = silc_channel_message_get_data(res->payload, &message_len);
209 /* Pass the message to application */
210 client->internal->ops->channel_message(
211 client, conn, clients[0], channel,
212 silc_channel_message_get_flags(res->payload),
213 message, message_len);
217 silc_channel_message_payload_free(res->payload);
218 silc_free(res->channel_id);
222 /* Process received message to a channel (or from a channel, really). This
223 decrypts the channel message with channel specific key and parses the
224 channel payload. Finally it displays the message on the screen. */
226 void silc_client_channel_message(SilcClient client,
227 SilcSocketConnection sock,
228 SilcPacketContext *packet)
230 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
231 SilcBuffer buffer = packet->buffer;
232 SilcChannelMessagePayload payload = NULL;
233 SilcChannelID *id = NULL;
234 SilcChannelEntry channel;
235 SilcClientEntry client_entry;
236 SilcClientID *client_id = NULL;
237 unsigned char *message;
238 SilcUInt32 message_len;
240 SILC_LOG_DEBUG(("Start"));
243 if (packet->dst_id_type != SILC_ID_CHANNEL)
246 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
250 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
254 /* Find the channel entry from channels on this connection */
255 channel = silc_client_get_channel_by_id(client, conn, id);
259 /* If there is no channel private key then just decrypt the message
260 with the channel key. If private keys are set then just go through
261 all private keys and check what decrypts correctly. */
262 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
263 /* Parse the channel message payload. This also decrypts the payload */
264 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
265 channel->channel_key,
268 /* If decryption failed and we have just performed channel key rekey
269 we will use the old key in decryption. If that fails too then we
270 cannot do more and will drop the packet. */
272 if (!channel->old_channel_key) {
276 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
277 channel->old_channel_key,
283 } else if (channel->private_keys) {
284 SilcChannelPrivateKey entry;
286 silc_dlist_start(channel->private_keys);
287 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
288 /* Parse the channel message payload. This also decrypts the payload */
289 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
295 if (entry == SILC_LIST_END)
301 /* Find client entry */
302 client_entry = silc_client_get_client_by_id(client, conn, client_id);
303 if (!client_entry || !client_entry->nickname) {
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,
309 silc_client_channel_message_cb,
316 if (!silc_client_on_channel(channel, client_entry)) {
317 SILC_LOG_WARNING(("Received channel message from client not on channel"));
321 message = silc_channel_message_get_data(payload, &message_len);
323 /* Pass the message to application */
324 client->internal->ops->channel_message(
325 client, conn, client_entry, channel,
326 silc_channel_message_get_flags(payload),
327 message, message_len);
331 silc_free(client_id);
333 silc_channel_message_payload_free(payload);
336 /* Timeout callback that is called after a short period of time after the
337 new channel key has been created. This removes the old channel key all
340 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
342 SilcChannelEntry channel = (SilcChannelEntry)context;
344 if (channel->old_channel_key)
345 silc_cipher_free(channel->old_channel_key);
346 if (channel->old_hmac)
347 silc_hmac_free(channel->old_hmac);
348 channel->old_channel_key = NULL;
349 channel->old_hmac = NULL;
350 channel->rekey_task = NULL;
353 /* Saves channel key from encoded `key_payload'. This is used when we
354 receive Channel Key Payload and when we are processing JOIN command
357 void silc_client_save_channel_key(SilcClient client,
358 SilcClientConnection conn,
359 SilcBuffer key_payload,
360 SilcChannelEntry channel)
362 unsigned char *id_string, *key, *cipher, *hmac, hash[32];
365 SilcChannelKeyPayload payload;
367 payload = silc_channel_key_payload_parse(key_payload->data,
372 id_string = silc_channel_key_get_id(payload, &tmp_len);
374 silc_channel_key_payload_free(payload);
378 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
380 silc_channel_key_payload_free(payload);
386 channel = silc_client_get_channel_by_id(client, conn, id);
391 hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
394 /* Save the old key for a short period of time so that we can decrypt
395 channel message even after the rekey if some client would be sending
396 messages with the old key after the rekey. */
397 if (channel->old_channel_key)
398 silc_cipher_free(channel->old_channel_key);
399 if (channel->old_hmac)
400 silc_hmac_free(channel->old_hmac);
401 if (channel->rekey_task)
402 silc_schedule_task_del(client->schedule, channel->rekey_task);
403 channel->old_channel_key = channel->channel_key;
404 channel->old_hmac = channel->hmac;
405 channel->rekey_task =
406 silc_schedule_task_add(client->schedule, 0,
407 silc_client_save_channel_key_rekey, channel,
408 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
410 /* Free the old channel key data */
411 silc_free(channel->key);
414 key = silc_channel_key_get_key(payload, &tmp_len);
415 cipher = silc_channel_key_get_cipher(payload, NULL);
416 channel->key_len = tmp_len * 8;
417 channel->key = silc_memdup(key, tmp_len);
419 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
420 client->internal->ops->say(
422 SILC_CLIENT_MESSAGE_AUDIT,
423 "Cannot talk to channel: unsupported cipher %s",
428 /* Set the cipher key */
429 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
431 /* Generate HMAC key from the channel key data and set it */
432 silc_hmac_alloc(hmac, NULL, &channel->hmac);
433 silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
434 silc_hmac_set_key(channel->hmac, hash,
435 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
436 memset(hash, 0, sizeof(hash));
440 silc_channel_key_payload_free(payload);
443 /* Processes received key for channel. The received key will be used
444 to protect the traffic on the channel for now on. Client must receive
445 the key to the channel before talking on the channel is possible.
446 This is the key that server has generated, this is not the channel
447 private key, it is entirely local setting. */
449 void silc_client_receive_channel_key(SilcClient client,
450 SilcSocketConnection sock,
453 SILC_LOG_DEBUG(("Received key for channel"));
456 silc_client_save_channel_key(client, sock->user_data, packet, NULL);
459 /* Adds private key for channel. This may be set only if the channel's mode
460 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
461 mode is not set. When channel has private key then the messages are
462 encrypted using that key. All clients on the channel must also know the
463 key in order to decrypt the messages. However, it is possible to have
464 several private keys per one channel. In this case only some of the
465 clients on the channel may know the one key and only some the other key.
467 If `cipher' and/or `hmac' is NULL then default values will be used
468 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
470 The private key for channel is optional. If it is not set then the
471 channel messages are encrypted using the channel key generated by the
472 server. However, setting the private key (or keys) for the channel
473 significantly adds security. If more than one key is set the library
474 will automatically try all keys at the message decryption phase. Note:
475 setting many keys slows down the decryption phase as all keys has to
476 be tried in order to find the correct decryption key. However, setting
477 a few keys does not have big impact to the decryption performace.
479 NOTE: that this is entirely local setting. The key set using this function
480 is not sent to the network at any phase.
482 NOTE: If the key material was originated by the SKE protocol (using
483 silc_client_send_key_agreement) then the `key' MUST be the
484 key->send_enc_key as this is dictated by the SILC protocol. However,
485 currently it is not expected that the SKE key material would be used
486 as channel private key. However, this API allows it. */
488 int silc_client_add_channel_private_key(SilcClient client,
489 SilcClientConnection conn,
490 SilcChannelEntry channel,
497 SilcChannelPrivateKey entry;
498 unsigned char hash[32];
499 SilcSKEKeyMaterial *keymat;
501 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
505 cipher = SILC_DEFAULT_CIPHER;
507 hmac = SILC_DEFAULT_HMAC;
509 if (!silc_cipher_is_supported(cipher))
512 if (!silc_hmac_is_supported(hmac))
515 /* Produce the key material */
516 keymat = silc_calloc(1, sizeof(*keymat));
517 if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
518 client->internal->md5hash, keymat)
519 != SILC_SKE_STATUS_OK)
522 /* Remove the current key, if it exists. */
523 if (channel->channel_key) {
524 silc_cipher_free(channel->channel_key);
525 memset(channel->key, 0, channel->key_len / 8);
526 silc_free(channel->key);
527 channel->channel_key = NULL;
529 channel->key_len = 0;
532 silc_hmac_free(channel->hmac);
533 channel->hmac = NULL;
536 if (!channel->private_keys)
537 channel->private_keys = silc_dlist_init();
540 entry = silc_calloc(1, sizeof(*entry));
541 entry->name = name ? strdup(name) : NULL;
542 entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
543 entry->key_len = keymat->enc_key_len / 8;
545 /* Allocate the cipher and set the key*/
546 silc_cipher_alloc(cipher, &entry->cipher);
547 silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
549 /* Generate HMAC key from the channel key data and set it */
550 silc_hmac_alloc(hmac, NULL, &entry->hmac);
551 silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key,
552 entry->key_len, hash);
553 silc_hmac_set_key(entry->hmac, hash,
554 silc_hash_len(silc_hmac_get_hash(entry->hmac)));
555 memset(hash, 0, sizeof(hash));
557 /* Add to the private keys list */
558 silc_dlist_add(channel->private_keys, entry);
560 if (!channel->curr_key)
561 channel->curr_key = entry;
563 /* Free the key material */
564 silc_ske_free_key_material(keymat);
569 /* Removes all private keys from the `channel'. The old channel key is used
570 after calling this to protect the channel messages. Returns FALSE on
571 on error, TRUE otherwise. */
573 int silc_client_del_channel_private_keys(SilcClient client,
574 SilcClientConnection conn,
575 SilcChannelEntry channel)
577 SilcChannelPrivateKey entry;
579 if (!channel->private_keys)
582 silc_dlist_start(channel->private_keys);
583 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
584 silc_dlist_del(channel->private_keys, entry);
585 memset(entry->key, 0, entry->key_len);
586 silc_free(entry->key);
587 silc_free(entry->name);
588 silc_cipher_free(entry->cipher);
589 silc_hmac_free(entry->hmac);
593 channel->curr_key = NULL;
595 silc_dlist_uninit(channel->private_keys);
596 channel->private_keys = NULL;
601 /* Removes and frees private key `key' from the channel `channel'. The `key'
602 is retrieved by calling the function silc_client_list_channel_private_keys.
603 The key is not used after this. If the key was last private key then the
604 old channel key is used hereafter to protect the channel messages. This
605 returns FALSE on error, TRUE otherwise. */
607 int silc_client_del_channel_private_key(SilcClient client,
608 SilcClientConnection conn,
609 SilcChannelEntry channel,
610 SilcChannelPrivateKey key)
612 SilcChannelPrivateKey entry;
614 if (!channel->private_keys)
617 silc_dlist_start(channel->private_keys);
618 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
620 if (channel->curr_key == entry)
621 channel->curr_key = NULL;
623 silc_dlist_del(channel->private_keys, entry);
624 memset(entry->key, 0, entry->key_len);
625 silc_free(entry->key);
626 silc_free(entry->name);
627 silc_cipher_free(entry->cipher);
628 silc_hmac_free(entry->hmac);
631 if (silc_dlist_count(channel->private_keys) == 0) {
632 silc_dlist_uninit(channel->private_keys);
633 channel->private_keys = NULL;
643 /* Returns array (pointers) of private keys associated to the `channel'.
644 The caller must free the array by calling the function
645 silc_client_free_channel_private_keys. The pointers in the array may be
646 used to delete the specific key by giving the pointer as argument to the
647 function silc_client_del_channel_private_key. */
649 SilcChannelPrivateKey *
650 silc_client_list_channel_private_keys(SilcClient client,
651 SilcClientConnection conn,
652 SilcChannelEntry channel,
653 SilcUInt32 *key_count)
655 SilcChannelPrivateKey *keys = NULL, entry;
656 SilcUInt32 count = 0;
658 if (!channel->private_keys)
661 silc_dlist_start(channel->private_keys);
662 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
663 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
674 /* Frees the SilcChannelPrivateKey array. */
676 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
677 SilcUInt32 key_count)
682 /* Sets the `key' to be used as current channel private key on the
683 `channel'. Packet sent after calling this function will be secured
686 void silc_client_current_channel_private_key(SilcClient client,
687 SilcClientConnection conn,
688 SilcChannelEntry channel,
689 SilcChannelPrivateKey key)
691 channel->curr_key = key;
694 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the
695 channel indicated by the `channel'. NULL if client is not joined on
698 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
699 SilcClientEntry client_entry)
703 if (silc_hash_table_find(channel->user_list, client_entry, NULL,