5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2003 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 bool 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;
55 assert(client && conn && channel);
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) {
107 SILC_LOG_ERROR(("No cipher and HMAC for channel"));
111 block_len = silc_cipher_get_block_len(cipher);
113 /* Encode the message payload. This also encrypts the message payload. */
114 payload = silc_message_payload_encode(flags, data, data_len, TRUE, FALSE,
115 cipher, hmac, client->rng, NULL,
116 client->private_key, client->sha1hash);
118 SILC_LOG_ERROR(("Error encoding channel message"));
122 /* Get data used in packet header encryption, keys and stuff. */
123 cipher = conn->internal->send_key;
124 hmac = conn->internal->hmac_send;
125 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
127 /* Set the packet context pointers. The destination ID is always
128 the Channel ID of the channel. Server and router will handle the
129 distribution of the packet. */
130 data = payload->data;
131 data_len = payload->len;
132 packetdata.flags = 0;
133 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
134 packetdata.src_id = conn->local_id_data;
135 packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
136 packetdata.src_id_type = SILC_ID_CLIENT;
137 packetdata.dst_id = id_string;
138 packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
139 packetdata.dst_id_type = SILC_ID_CHANNEL;
140 data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
141 packetdata.src_id_len +
142 packetdata.dst_id_len);
143 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
144 packetdata.src_id_len + packetdata.dst_id_len;
145 SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
146 packetdata.src_id_len +
147 packetdata.dst_id_len), block_len, packetdata.padlen);
149 /* Create the outgoing packet */
150 if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
151 data, data_len, (const SilcBuffer)&packet)) {
152 SILC_LOG_ERROR(("Error assembling packet"));
156 /* Encrypt the header and padding of the packet. This is encrypted
157 with normal session key shared with our server. */
158 silc_packet_encrypt(cipher, hmac, conn->internal->psn_send++,
159 (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN +
160 packetdata.src_id_len + packetdata.dst_id_len +
163 SILC_LOG_HEXDUMP(("Packet to channel, len %d", packet.len),
164 packet.data, packet.len);
166 /* Now actually send the packet */
167 silc_client_packet_send_real(client, sock, force_send);
169 /* Check for mandatory rekey */
170 if (conn->internal->psn_send == SILC_CLIENT_REKEY_THRESHOLD)
171 silc_schedule_task_add(client->schedule, sock->sock,
172 silc_client_rekey_callback, sock, 0, 1,
173 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
178 silc_buffer_free(payload);
179 silc_free(id_string);
185 SilcMessagePayload payload;
186 SilcChannelID *channel_id;
187 } *SilcChannelClientResolve;
189 static void silc_client_channel_message_cb(SilcClient client,
190 SilcClientConnection conn,
191 SilcClientEntry *clients,
192 SilcUInt32 clients_count,
195 SilcChannelClientResolve res = (SilcChannelClientResolve)context;
197 if (clients_count == 1) {
198 SilcChannelEntry channel;
199 unsigned char *message;
200 SilcUInt32 message_len;
202 channel = silc_client_get_channel_by_id(client, conn, res->channel_id);
206 /* If this client is not on channel, add it there since it clearly
208 if (!silc_client_on_channel(channel, clients[0])) {
209 SilcChannelUser chu = silc_calloc(1, sizeof(*chu));
210 chu->client = clients[0];
211 chu->channel = channel;
212 silc_hash_table_add(channel->user_list, clients[0], chu);
213 silc_hash_table_add(clients[0]->channels, channel, chu);
216 message = silc_message_get_data(res->payload, &message_len);
218 /* Pass the message to application */
219 client->internal->ops->channel_message(
220 client, conn, clients[0], channel, res->payload,
221 silc_message_get_flags(res->payload),
222 message, message_len);
226 silc_message_payload_free(res->payload);
227 silc_free(res->channel_id);
231 /* Process received message to a channel (or from a channel, really). This
232 decrypts the channel message with channel specific key and parses the
233 message payload. Finally it displays the message on the screen. */
235 void silc_client_channel_message(SilcClient client,
236 SilcSocketConnection sock,
237 SilcPacketContext *packet)
239 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
240 SilcBuffer buffer = packet->buffer;
241 SilcMessagePayload payload = NULL;
242 SilcChannelID *id = NULL;
243 SilcChannelEntry channel;
244 SilcClientEntry client_entry;
245 SilcClientID *client_id = NULL;
246 unsigned char *message;
247 SilcUInt32 message_len;
249 SILC_LOG_DEBUG(("Received channel message"));
252 if (packet->dst_id_type != SILC_ID_CHANNEL)
255 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
259 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
263 /* Find the channel entry from channels on this connection */
264 channel = silc_client_get_channel_by_id(client, conn, id);
268 /* If there is no channel private key then just decrypt the message
269 with the channel key. If private keys are set then just go through
270 all private keys and check what decrypts correctly. */
271 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
272 /* Parse the channel message payload. This also decrypts the payload */
273 payload = silc_message_payload_parse(buffer->data, buffer->len, FALSE,
274 FALSE, channel->channel_key,
277 /* If decryption failed and we have just performed channel key rekey
278 we will use the old key in decryption. If that fails too then we
279 cannot do more and will drop the packet. */
285 if (!channel->old_channel_keys ||
286 !silc_dlist_count(channel->old_channel_keys))
289 SILC_LOG_DEBUG(("Attempting to decrypt with old channel key(s)"));
291 silc_dlist_end(channel->old_channel_keys);
292 silc_dlist_end(channel->old_hmacs);
293 for (i = 0; i < silc_dlist_count(channel->old_channel_keys); i++) {
294 key = silc_dlist_get(channel->old_channel_keys);
295 hmac = silc_dlist_get(channel->old_hmacs);
299 payload = silc_message_payload_parse(buffer->data, buffer->len,
300 FALSE, FALSE, key, hmac);
307 } else if (channel->private_keys) {
308 SilcChannelPrivateKey entry;
310 silc_dlist_start(channel->private_keys);
311 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
312 /* Parse the message payload. This also decrypts the payload */
313 payload = silc_message_payload_parse(buffer->data, buffer->len,
315 entry->cipher, entry->hmac);
319 if (entry == SILC_LIST_END)
325 /* Find client entry */
326 client_entry = silc_client_get_client_by_id(client, conn, client_id);
327 if (!client_entry || !client_entry->nickname ||
328 !silc_client_on_channel(channel, client_entry)) {
329 /* Resolve the client info */
330 SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
331 res->payload = payload;
332 res->channel_id = id;
333 silc_client_get_client_by_id_resolve(client, conn, client_id, NULL,
334 silc_client_channel_message_cb,
341 message = silc_message_get_data(payload, &message_len);
343 /* Pass the message to application */
344 client->internal->ops->channel_message(
345 client, conn, client_entry, channel, payload,
346 silc_message_get_flags(payload),
347 message, message_len);
351 silc_free(client_id);
353 silc_message_payload_free(payload);
356 /* Timeout callback that is called after a short period of time after the
357 new channel key has been created. This removes the first channel key
360 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
362 SilcChannelEntry channel = (SilcChannelEntry)context;
366 if (channel->old_channel_keys) {
367 silc_dlist_start(channel->old_channel_keys);
368 key = silc_dlist_get(channel->old_channel_keys);
370 silc_dlist_del(channel->old_channel_keys, key);
371 silc_cipher_free(key);
375 if (channel->old_hmacs) {
376 silc_dlist_start(channel->old_hmacs);
377 hmac = silc_dlist_get(channel->old_hmacs);
379 silc_dlist_del(channel->old_hmacs, hmac);
380 silc_hmac_free(hmac);
385 /* Saves channel key from encoded `key_payload'. This is used when we
386 receive Channel Key Payload and when we are processing JOIN command
389 void silc_client_save_channel_key(SilcClient client,
390 SilcClientConnection conn,
391 SilcBuffer key_payload,
392 SilcChannelEntry channel)
394 unsigned char *id_string, *key, *cipher, *hmac, hash[32];
397 SilcChannelKeyPayload payload;
399 payload = silc_channel_key_payload_parse(key_payload->data,
404 id_string = silc_channel_key_get_id(payload, &tmp_len);
406 silc_channel_key_payload_free(payload);
410 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
412 silc_channel_key_payload_free(payload);
418 channel = silc_client_get_channel_by_id(client, conn, id);
423 hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
426 /* Save the old key for a short period of time so that we can decrypt
427 channel message even after the rekey if some client would be sending
428 messages with the old key after the rekey. */
429 if (!channel->old_channel_keys)
430 channel->old_channel_keys = silc_dlist_init();
431 if (!channel->old_hmacs)
432 channel->old_hmacs = silc_dlist_init();
433 silc_dlist_add(channel->old_channel_keys, channel->channel_key);
434 silc_dlist_add(channel->old_hmacs, channel->hmac);
435 silc_schedule_task_add(client->schedule, 0,
436 silc_client_save_channel_key_rekey, channel,
437 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
439 /* Free the old channel key data */
440 silc_free(channel->key);
443 key = silc_channel_key_get_key(payload, &tmp_len);
444 cipher = silc_channel_key_get_cipher(payload, NULL);
445 channel->key_len = tmp_len * 8;
446 channel->key = silc_memdup(key, tmp_len);
448 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
449 client->internal->ops->say(
451 SILC_CLIENT_MESSAGE_AUDIT,
452 "Cannot talk to channel: unsupported cipher %s",
457 /* Set the cipher key */
458 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
460 /* Generate HMAC key from the channel key data and set it */
461 silc_hmac_alloc(hmac, NULL, &channel->hmac);
462 silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
463 silc_hmac_set_key(channel->hmac, hash,
464 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
465 memset(hash, 0, sizeof(hash));
469 silc_channel_key_payload_free(payload);
472 /* Processes received key for channel. The received key will be used
473 to protect the traffic on the channel for now on. Client must receive
474 the key to the channel before talking on the channel is possible.
475 This is the key that server has generated, this is not the channel
476 private key, it is entirely local setting. */
478 void silc_client_receive_channel_key(SilcClient client,
479 SilcSocketConnection sock,
482 SILC_LOG_DEBUG(("Received key for channel"));
485 silc_client_save_channel_key(client, sock->user_data, packet, NULL);
488 /* Adds private key for channel. This may be set only if the channel's mode
489 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
490 mode is not set. When channel has private key then the messages are
491 encrypted using that key. All clients on the channel must also know the
492 key in order to decrypt the messages. However, it is possible to have
493 several private keys per one channel. In this case only some of the
494 clients on the channel may know the one key and only some the other key.
496 If `cipher' and/or `hmac' is NULL then default values will be used
497 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
499 The private key for channel is optional. If it is not set then the
500 channel messages are encrypted using the channel key generated by the
501 server. However, setting the private key (or keys) for the channel
502 significantly adds security. If more than one key is set the library
503 will automatically try all keys at the message decryption phase. Note:
504 setting many keys slows down the decryption phase as all keys has to
505 be tried in order to find the correct decryption key. However, setting
506 a few keys does not have big impact to the decryption performace.
508 NOTE: that this is entirely local setting. The key set using this function
509 is not sent to the network at any phase.
511 NOTE: If the key material was originated by the SKE protocol (using
512 silc_client_send_key_agreement) then the `key' MUST be the
513 key->send_enc_key as this is dictated by the SILC protocol. However,
514 currently it is not expected that the SKE key material would be used
515 as channel private key. However, this API allows it. */
517 bool silc_client_add_channel_private_key(SilcClient client,
518 SilcClientConnection conn,
519 SilcChannelEntry channel,
526 SilcChannelPrivateKey entry;
527 unsigned char hash[32];
528 SilcSKEKeyMaterial *keymat;
530 assert(client && channel);
532 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
536 cipher = SILC_DEFAULT_CIPHER;
538 hmac = SILC_DEFAULT_HMAC;
540 if (!silc_cipher_is_supported(cipher))
543 if (!silc_hmac_is_supported(hmac))
546 /* Produce the key material */
547 keymat = silc_calloc(1, sizeof(*keymat));
548 if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
549 client->sha1hash, keymat)
550 != SILC_SKE_STATUS_OK)
553 /* Remove the current key, if it exists. */
554 if (channel->channel_key) {
555 silc_cipher_free(channel->channel_key);
556 memset(channel->key, 0, channel->key_len / 8);
557 silc_free(channel->key);
558 channel->channel_key = NULL;
560 channel->key_len = 0;
563 silc_hmac_free(channel->hmac);
564 channel->hmac = NULL;
567 if (!channel->private_keys)
568 channel->private_keys = silc_dlist_init();
571 entry = silc_calloc(1, sizeof(*entry));
572 entry->name = name ? strdup(name) : NULL;
573 entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
574 entry->key_len = keymat->enc_key_len / 8;
576 /* Allocate the cipher and set the key*/
577 silc_cipher_alloc(cipher, &entry->cipher);
578 silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
580 /* Generate HMAC key from the channel key data and set it */
581 silc_hmac_alloc(hmac, NULL, &entry->hmac);
582 silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key,
583 entry->key_len, hash);
584 silc_hmac_set_key(entry->hmac, hash,
585 silc_hash_len(silc_hmac_get_hash(entry->hmac)));
586 memset(hash, 0, sizeof(hash));
588 /* Add to the private keys list */
589 silc_dlist_add(channel->private_keys, entry);
591 if (!channel->curr_key)
592 channel->curr_key = entry;
594 /* Free the key material */
595 silc_ske_free_key_material(keymat);
600 /* Removes all private keys from the `channel'. The old channel key is used
601 after calling this to protect the channel messages. Returns FALSE on
602 on error, TRUE otherwise. */
604 bool silc_client_del_channel_private_keys(SilcClient client,
605 SilcClientConnection conn,
606 SilcChannelEntry channel)
608 SilcChannelPrivateKey entry;
610 assert(client && channel);
612 if (!channel->private_keys)
615 silc_dlist_start(channel->private_keys);
616 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
617 silc_dlist_del(channel->private_keys, entry);
618 memset(entry->key, 0, entry->key_len);
619 silc_free(entry->key);
620 silc_free(entry->name);
621 silc_cipher_free(entry->cipher);
622 silc_hmac_free(entry->hmac);
626 channel->curr_key = NULL;
628 silc_dlist_uninit(channel->private_keys);
629 channel->private_keys = NULL;
634 /* Removes and frees private key `key' from the channel `channel'. The `key'
635 is retrieved by calling the function silc_client_list_channel_private_keys.
636 The key is not used after this. If the key was last private key then the
637 old channel key is used hereafter to protect the channel messages. This
638 returns FALSE on error, TRUE otherwise. */
640 bool silc_client_del_channel_private_key(SilcClient client,
641 SilcClientConnection conn,
642 SilcChannelEntry channel,
643 SilcChannelPrivateKey key)
645 SilcChannelPrivateKey entry;
647 assert(client && channel);
649 if (!channel->private_keys)
652 silc_dlist_start(channel->private_keys);
653 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
655 if (channel->curr_key == entry)
656 channel->curr_key = NULL;
658 silc_dlist_del(channel->private_keys, entry);
659 memset(entry->key, 0, entry->key_len);
660 silc_free(entry->key);
661 silc_free(entry->name);
662 silc_cipher_free(entry->cipher);
663 silc_hmac_free(entry->hmac);
666 if (silc_dlist_count(channel->private_keys) == 0) {
667 silc_dlist_uninit(channel->private_keys);
668 channel->private_keys = NULL;
678 /* Returns array (pointers) of private keys associated to the `channel'.
679 The caller must free the array by calling the function
680 silc_client_free_channel_private_keys. The pointers in the array may be
681 used to delete the specific key by giving the pointer as argument to the
682 function silc_client_del_channel_private_key. */
684 SilcChannelPrivateKey *
685 silc_client_list_channel_private_keys(SilcClient client,
686 SilcClientConnection conn,
687 SilcChannelEntry channel,
688 SilcUInt32 *key_count)
690 SilcChannelPrivateKey *keys = NULL, entry;
691 SilcUInt32 count = 0;
693 assert(client && channel);
695 if (!channel->private_keys)
698 silc_dlist_start(channel->private_keys);
699 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
700 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
711 /* Frees the SilcChannelPrivateKey array. */
713 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
714 SilcUInt32 key_count)
719 /* Sets the `key' to be used as current channel private key on the
720 `channel'. Packet sent after calling this function will be secured
723 void silc_client_current_channel_private_key(SilcClient client,
724 SilcClientConnection conn,
725 SilcChannelEntry channel,
726 SilcChannelPrivateKey key)
728 assert(client && channel);
729 channel->curr_key = key;
732 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the
733 channel indicated by the `channel'. NULL if client is not joined on
736 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
737 SilcClientEntry client_entry)
741 if (silc_hash_table_find(channel->user_list, client_entry, NULL,