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->internal->md5hash, channel->iv, iv_len,
120 /* Encode the channel payload. This also encrypts the message payload. */
121 payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len,
122 channel->iv, cipher, hmac,
125 /* Get data used in packet header encryption, keys and stuff. */
126 cipher = conn->send_key;
127 hmac = conn->hmac_send;
128 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
130 /* Set the packet context pointers. The destination ID is always
131 the Channel ID of the channel. Server and router will handle the
132 distribution of the packet. */
133 data = payload->data;
134 data_len = payload->len;
135 packetdata.flags = 0;
136 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
137 packetdata.src_id = conn->local_id_data;
138 packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
139 packetdata.src_id_type = SILC_ID_CLIENT;
140 packetdata.dst_id = id_string;
141 packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
142 packetdata.dst_id_type = SILC_ID_CHANNEL;
143 data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
144 packetdata.src_id_len +
145 packetdata.dst_id_len);
146 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
147 packetdata.src_id_len + packetdata.dst_id_len;
148 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
149 packetdata.src_id_len +
150 packetdata.dst_id_len), block_len);
152 /* Create the outgoing packet */
153 if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
154 data, data_len, (const SilcBuffer)&packet)) {
155 SILC_LOG_ERROR(("Error assembling packet"));
159 /* Encrypt the header and padding of the packet. This is encrypted
160 with normal session key shared with our server. */
161 silc_packet_encrypt(cipher, hmac, conn->psn_send++,
162 (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN +
163 packetdata.src_id_len + packetdata.dst_id_len +
166 SILC_LOG_HEXDUMP(("Packet to channel, len %d", packet.len),
167 packet.data, packet.len);
169 /* Now actually send the packet */
170 silc_client_packet_send_real(client, sock, force_send);
173 silc_buffer_free(payload);
174 silc_free(id_string);
178 SilcChannelMessagePayload payload;
179 SilcChannelID *channel_id;
180 } *SilcChannelClientResolve;
182 static void silc_client_channel_message_cb(SilcClient client,
183 SilcClientConnection conn,
184 SilcClientEntry *clients,
185 SilcUInt32 clients_count,
188 SilcChannelClientResolve res = (SilcChannelClientResolve)context;
190 if (clients_count == 1) {
191 SilcChannelEntry channel;
192 unsigned char *message;
193 SilcUInt32 message_len;
195 channel = silc_client_get_channel_by_id(client, conn, res->channel_id);
199 /* If this client is not on channel, add it there since it clearly
201 if (!silc_client_on_channel(channel, clients[0])) {
202 SilcChannelUser chu = silc_calloc(1, sizeof(*chu));
203 chu->client = clients[0];
204 chu->channel = channel;
205 silc_hash_table_add(channel->user_list, clients[0], chu);
206 silc_hash_table_add(clients[0]->channels, channel, chu);
209 message = silc_channel_message_get_data(res->payload, &message_len);
211 /* Pass the message to application */
212 client->internal->ops->channel_message(
213 client, conn, clients[0], channel,
214 silc_channel_message_get_flags(res->payload),
215 message, message_len);
219 silc_channel_message_payload_free(res->payload);
220 silc_free(res->channel_id);
224 /* Process received message to a channel (or from a channel, really). This
225 decrypts the channel message with channel specific key and parses the
226 channel payload. Finally it displays the message on the screen. */
228 void silc_client_channel_message(SilcClient client,
229 SilcSocketConnection sock,
230 SilcPacketContext *packet)
232 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
233 SilcBuffer buffer = packet->buffer;
234 SilcChannelMessagePayload payload = NULL;
235 SilcChannelID *id = NULL;
236 SilcChannelEntry channel;
237 SilcClientEntry client_entry;
238 SilcClientID *client_id = NULL;
239 unsigned char *message;
240 SilcUInt32 message_len;
242 SILC_LOG_DEBUG(("Start"));
245 if (packet->dst_id_type != SILC_ID_CHANNEL)
248 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
252 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
256 /* Find the channel entry from channels on this connection */
257 channel = silc_client_get_channel_by_id(client, conn, id);
261 /* If there is no channel private key then just decrypt the message
262 with the channel key. If private keys are set then just go through
263 all private keys and check what decrypts correctly. */
264 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
265 /* Parse the channel message payload. This also decrypts the payload */
266 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
267 channel->channel_key,
270 /* If decryption failed and we have just performed channel key rekey
271 we will use the old key in decryption. If that fails too then we
272 cannot do more and will drop the packet. */
274 if (!channel->old_channel_key) {
278 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
279 channel->old_channel_key,
285 } else if (channel->private_keys) {
286 SilcChannelPrivateKey entry;
288 silc_dlist_start(channel->private_keys);
289 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
290 /* Parse the channel message payload. This also decrypts the payload */
291 payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
297 if (entry == SILC_LIST_END)
303 /* Find client entry */
304 client_entry = silc_client_get_client_by_id(client, conn, client_id);
305 if (!client_entry || !client_entry->nickname) {
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,
311 silc_client_channel_message_cb,
318 if (!silc_client_on_channel(channel, client_entry)) {
319 SILC_LOG_WARNING(("Received channel message from client not on channel"));
323 message = silc_channel_message_get_data(payload, &message_len);
325 /* Pass the message to application */
326 client->internal->ops->channel_message(
327 client, conn, client_entry, channel,
328 silc_channel_message_get_flags(payload),
329 message, message_len);
333 silc_free(client_id);
335 silc_channel_message_payload_free(payload);
338 /* Timeout callback that is called after a short period of time after the
339 new channel key has been created. This removes the old channel key all
342 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
344 SilcChannelEntry channel = (SilcChannelEntry)context;
346 if (channel->old_channel_key)
347 silc_cipher_free(channel->old_channel_key);
348 if (channel->old_hmac)
349 silc_hmac_free(channel->old_hmac);
350 channel->old_channel_key = NULL;
351 channel->old_hmac = NULL;
352 channel->rekey_task = NULL;
355 /* Saves channel key from encoded `key_payload'. This is used when we
356 receive Channel Key Payload and when we are processing JOIN command
359 void silc_client_save_channel_key(SilcClient client,
360 SilcClientConnection conn,
361 SilcBuffer key_payload,
362 SilcChannelEntry channel)
364 unsigned char *id_string, *key, *cipher, *hmac, hash[32];
367 SilcChannelKeyPayload payload;
369 payload = silc_channel_key_payload_parse(key_payload->data,
374 id_string = silc_channel_key_get_id(payload, &tmp_len);
376 silc_channel_key_payload_free(payload);
380 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
382 silc_channel_key_payload_free(payload);
388 channel = silc_client_get_channel_by_id(client, conn, id);
393 hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
396 /* Save the old key for a short period of time so that we can decrypt
397 channel message even after the rekey if some client would be sending
398 messages with the old key after the rekey. */
399 if (channel->old_channel_key)
400 silc_cipher_free(channel->old_channel_key);
401 if (channel->old_hmac)
402 silc_hmac_free(channel->old_hmac);
403 if (channel->rekey_task)
404 silc_schedule_task_del(client->schedule, channel->rekey_task);
405 channel->old_channel_key = channel->channel_key;
406 channel->old_hmac = channel->hmac;
407 channel->rekey_task =
408 silc_schedule_task_add(client->schedule, 0,
409 silc_client_save_channel_key_rekey, channel,
410 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
412 /* Free the old channel key data */
413 silc_free(channel->key);
416 key = silc_channel_key_get_key(payload, &tmp_len);
417 cipher = silc_channel_key_get_cipher(payload, NULL);
418 channel->key_len = tmp_len * 8;
419 channel->key = silc_memdup(key, tmp_len);
421 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
422 client->internal->ops->say(
424 SILC_CLIENT_MESSAGE_AUDIT,
425 "Cannot talk to channel: unsupported cipher %s",
430 /* Set the cipher key */
431 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
433 /* Generate HMAC key from the channel key data and set it */
434 silc_hmac_alloc(hmac, NULL, &channel->hmac);
435 silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
436 silc_hmac_set_key(channel->hmac, hash,
437 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
438 memset(hash, 0, sizeof(hash));
442 silc_channel_key_payload_free(payload);
445 /* Processes received key for channel. The received key will be used
446 to protect the traffic on the channel for now on. Client must receive
447 the key to the channel before talking on the channel is possible.
448 This is the key that server has generated, this is not the channel
449 private key, it is entirely local setting. */
451 void silc_client_receive_channel_key(SilcClient client,
452 SilcSocketConnection sock,
455 SILC_LOG_DEBUG(("Received key for channel"));
458 silc_client_save_channel_key(client, sock->user_data, packet, NULL);
461 /* Adds private key for channel. This may be set only if the channel's mode
462 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
463 mode is not set. When channel has private key then the messages are
464 encrypted using that key. All clients on the channel must also know the
465 key in order to decrypt the messages. However, it is possible to have
466 several private keys per one channel. In this case only some of the
467 clients on the channel may know the one key and only some the other key.
469 If `cipher' and/or `hmac' is NULL then default values will be used
470 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
472 The private key for channel is optional. If it is not set then the
473 channel messages are encrypted using the channel key generated by the
474 server. However, setting the private key (or keys) for the channel
475 significantly adds security. If more than one key is set the library
476 will automatically try all keys at the message decryption phase. Note:
477 setting many keys slows down the decryption phase as all keys has to
478 be tried in order to find the correct decryption key. However, setting
479 a few keys does not have big impact to the decryption performace.
481 NOTE: that this is entirely local setting. The key set using this function
482 is not sent to the network at any phase.
484 NOTE: If the key material was originated by the SKE protocol (using
485 silc_client_send_key_agreement) then the `key' MUST be the
486 key->send_enc_key as this is dictated by the SILC protocol. However,
487 currently it is not expected that the SKE key material would be used
488 as channel private key. However, this API allows it. */
490 int silc_client_add_channel_private_key(SilcClient client,
491 SilcClientConnection conn,
492 SilcChannelEntry channel,
499 SilcChannelPrivateKey entry;
500 unsigned char hash[32];
501 SilcSKEKeyMaterial *keymat;
503 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
507 cipher = SILC_DEFAULT_CIPHER;
509 hmac = SILC_DEFAULT_HMAC;
511 if (!silc_cipher_is_supported(cipher))
514 if (!silc_hmac_is_supported(hmac))
517 /* Produce the key material */
518 keymat = silc_calloc(1, sizeof(*keymat));
519 if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
520 client->internal->md5hash, keymat)
521 != SILC_SKE_STATUS_OK)
524 /* Remove the current key, if it exists. */
525 if (channel->channel_key) {
526 silc_cipher_free(channel->channel_key);
527 memset(channel->key, 0, channel->key_len / 8);
528 silc_free(channel->key);
529 channel->channel_key = NULL;
531 channel->key_len = 0;
534 silc_hmac_free(channel->hmac);
535 channel->hmac = NULL;
538 if (!channel->private_keys)
539 channel->private_keys = silc_dlist_init();
542 entry = silc_calloc(1, sizeof(*entry));
543 entry->name = name ? strdup(name) : NULL;
544 entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
545 entry->key_len = keymat->enc_key_len / 8;
547 /* Allocate the cipher and set the key*/
548 silc_cipher_alloc(cipher, &entry->cipher);
549 silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
551 /* Generate HMAC key from the channel key data and set it */
552 silc_hmac_alloc(hmac, NULL, &entry->hmac);
553 silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key,
554 entry->key_len, hash);
555 silc_hmac_set_key(entry->hmac, hash,
556 silc_hash_len(silc_hmac_get_hash(entry->hmac)));
557 memset(hash, 0, sizeof(hash));
559 /* Add to the private keys list */
560 silc_dlist_add(channel->private_keys, entry);
562 if (!channel->curr_key)
563 channel->curr_key = entry;
565 /* Free the key material */
566 silc_ske_free_key_material(keymat);
571 /* Removes all private keys from the `channel'. The old channel key is used
572 after calling this to protect the channel messages. Returns FALSE on
573 on error, TRUE otherwise. */
575 int silc_client_del_channel_private_keys(SilcClient client,
576 SilcClientConnection conn,
577 SilcChannelEntry channel)
579 SilcChannelPrivateKey entry;
581 if (!channel->private_keys)
584 silc_dlist_start(channel->private_keys);
585 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
586 silc_dlist_del(channel->private_keys, entry);
587 memset(entry->key, 0, entry->key_len);
588 silc_free(entry->key);
589 silc_free(entry->name);
590 silc_cipher_free(entry->cipher);
591 silc_hmac_free(entry->hmac);
595 channel->curr_key = NULL;
597 silc_dlist_uninit(channel->private_keys);
598 channel->private_keys = NULL;
603 /* Removes and frees private key `key' from the channel `channel'. The `key'
604 is retrieved by calling the function silc_client_list_channel_private_keys.
605 The key is not used after this. If the key was last private key then the
606 old channel key is used hereafter to protect the channel messages. This
607 returns FALSE on error, TRUE otherwise. */
609 int silc_client_del_channel_private_key(SilcClient client,
610 SilcClientConnection conn,
611 SilcChannelEntry channel,
612 SilcChannelPrivateKey key)
614 SilcChannelPrivateKey entry;
616 if (!channel->private_keys)
619 silc_dlist_start(channel->private_keys);
620 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
622 if (channel->curr_key == entry)
623 channel->curr_key = NULL;
625 silc_dlist_del(channel->private_keys, entry);
626 memset(entry->key, 0, entry->key_len);
627 silc_free(entry->key);
628 silc_free(entry->name);
629 silc_cipher_free(entry->cipher);
630 silc_hmac_free(entry->hmac);
633 if (silc_dlist_count(channel->private_keys) == 0) {
634 silc_dlist_uninit(channel->private_keys);
635 channel->private_keys = NULL;
645 /* Returns array (pointers) of private keys associated to the `channel'.
646 The caller must free the array by calling the function
647 silc_client_free_channel_private_keys. The pointers in the array may be
648 used to delete the specific key by giving the pointer as argument to the
649 function silc_client_del_channel_private_key. */
651 SilcChannelPrivateKey *
652 silc_client_list_channel_private_keys(SilcClient client,
653 SilcClientConnection conn,
654 SilcChannelEntry channel,
655 SilcUInt32 *key_count)
657 SilcChannelPrivateKey *keys = NULL, entry;
658 SilcUInt32 count = 0;
660 if (!channel->private_keys)
663 silc_dlist_start(channel->private_keys);
664 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
665 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
676 /* Frees the SilcChannelPrivateKey array. */
678 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
679 SilcUInt32 key_count)
684 /* Sets the `key' to be used as current channel private key on the
685 `channel'. Packet sent after calling this function will be secured
688 void silc_client_current_channel_private_key(SilcClient client,
689 SilcClientConnection conn,
690 SilcChannelEntry channel,
691 SilcChannelPrivateKey key)
693 channel->curr_key = key;
696 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the
697 channel indicated by the `channel'. NULL if client is not joined on
700 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
701 SilcClientEntry client_entry)
705 if (silc_hash_table_find(channel->user_list, client_entry, NULL,