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);
114 /* Get data used in packet header encryption, keys and stuff. */
115 cipher = conn->internal->send_key;
116 hmac = conn->internal->hmac_send;
117 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
119 /* Set the packet context pointers. The destination ID is always
120 the Channel ID of the channel. Server and router will handle the
121 distribution of the packet. */
122 data = payload->data;
123 data_len = payload->len;
124 packetdata.flags = 0;
125 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
126 packetdata.src_id = conn->local_id_data;
127 packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
128 packetdata.src_id_type = SILC_ID_CLIENT;
129 packetdata.dst_id = id_string;
130 packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
131 packetdata.dst_id_type = SILC_ID_CHANNEL;
132 data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
133 packetdata.src_id_len +
134 packetdata.dst_id_len);
135 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
136 packetdata.src_id_len + packetdata.dst_id_len;
137 SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
138 packetdata.src_id_len +
139 packetdata.dst_id_len), block_len, packetdata.padlen);
141 /* Create the outgoing packet */
142 if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
143 data, data_len, (const SilcBuffer)&packet)) {
144 SILC_LOG_ERROR(("Error assembling packet"));
148 /* Encrypt the header and padding of the packet. This is encrypted
149 with normal session key shared with our server. */
150 silc_packet_encrypt(cipher, hmac, conn->internal->psn_send++,
151 (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN +
152 packetdata.src_id_len + packetdata.dst_id_len +
155 SILC_LOG_HEXDUMP(("Packet to channel, len %d", packet.len),
156 packet.data, packet.len);
158 /* Now actually send the packet */
159 silc_client_packet_send_real(client, sock, force_send);
161 /* Check for mandatory rekey */
162 if (conn->internal->psn_send == SILC_CLIENT_REKEY_THRESHOLD)
163 silc_schedule_task_add(client->schedule, sock->sock,
164 silc_client_rekey_callback, sock, 0, 1,
165 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
168 silc_buffer_free(payload);
169 silc_free(id_string);
173 SilcMessagePayload payload;
174 SilcChannelID *channel_id;
175 } *SilcChannelClientResolve;
177 static void silc_client_channel_message_cb(SilcClient client,
178 SilcClientConnection conn,
179 SilcClientEntry *clients,
180 SilcUInt32 clients_count,
183 SilcChannelClientResolve res = (SilcChannelClientResolve)context;
185 if (clients_count == 1) {
186 SilcChannelEntry channel;
187 unsigned char *message;
188 SilcUInt32 message_len;
190 channel = silc_client_get_channel_by_id(client, conn, res->channel_id);
194 /* If this client is not on channel, add it there since it clearly
196 if (!silc_client_on_channel(channel, clients[0])) {
197 SilcChannelUser chu = silc_calloc(1, sizeof(*chu));
198 chu->client = clients[0];
199 chu->channel = channel;
200 silc_hash_table_add(channel->user_list, clients[0], chu);
201 silc_hash_table_add(clients[0]->channels, channel, chu);
204 message = silc_message_get_data(res->payload, &message_len);
206 /* Pass the message to application */
207 client->internal->ops->channel_message(
208 client, conn, clients[0], channel,
209 silc_message_get_flags(res->payload),
210 message, message_len);
214 silc_message_payload_free(res->payload);
215 silc_free(res->channel_id);
219 /* Process received message to a channel (or from a channel, really). This
220 decrypts the channel message with channel specific key and parses the
221 message payload. Finally it displays the message on the screen. */
223 void silc_client_channel_message(SilcClient client,
224 SilcSocketConnection sock,
225 SilcPacketContext *packet)
227 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
228 SilcBuffer buffer = packet->buffer;
229 SilcMessagePayload payload = NULL;
230 SilcChannelID *id = NULL;
231 SilcChannelEntry channel;
232 SilcClientEntry client_entry;
233 SilcClientID *client_id = NULL;
234 unsigned char *message;
235 SilcUInt32 message_len;
237 SILC_LOG_DEBUG(("Start"));
240 if (packet->dst_id_type != SILC_ID_CHANNEL)
243 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
247 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
251 /* Find the channel entry from channels on this connection */
252 channel = silc_client_get_channel_by_id(client, conn, id);
256 /* If there is no channel private key then just decrypt the message
257 with the channel key. If private keys are set then just go through
258 all private keys and check what decrypts correctly. */
259 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
260 /* Parse the channel message payload. This also decrypts the payload */
261 payload = silc_message_payload_parse(buffer->data, buffer->len, FALSE,
262 FALSE, channel->channel_key,
265 /* If decryption failed and we have just performed channel key rekey
266 we will use the old key in decryption. If that fails too then we
267 cannot do more and will drop the packet. */
269 if (!channel->old_channel_key) {
273 payload = silc_message_payload_parse(buffer->data, buffer->len,
275 channel->old_channel_key,
281 } else if (channel->private_keys) {
282 SilcChannelPrivateKey entry;
284 silc_dlist_start(channel->private_keys);
285 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
286 /* Parse the message payload. This also decrypts the payload */
287 payload = silc_message_payload_parse(buffer->data, buffer->len,
289 entry->cipher, entry->hmac);
293 if (entry == SILC_LIST_END)
299 /* Find client entry */
300 client_entry = silc_client_get_client_by_id(client, conn, client_id);
301 if (!client_entry || !client_entry->nickname ||
302 !silc_client_on_channel(channel, client_entry)) {
303 /* Resolve the client info */
304 SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
305 res->payload = payload;
306 res->channel_id = id;
307 silc_client_get_client_by_id_resolve(client, conn, client_id, NULL,
308 silc_client_channel_message_cb,
315 message = silc_message_get_data(payload, &message_len);
317 /* Pass the message to application */
318 client->internal->ops->channel_message(
319 client, conn, client_entry, channel,
320 silc_message_get_flags(payload),
321 message, message_len);
325 silc_free(client_id);
327 silc_message_payload_free(payload);
330 /* Timeout callback that is called after a short period of time after the
331 new channel key has been created. This removes the old channel key all
334 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
336 SilcChannelEntry channel = (SilcChannelEntry)context;
338 if (channel->old_channel_key)
339 silc_cipher_free(channel->old_channel_key);
340 if (channel->old_hmac)
341 silc_hmac_free(channel->old_hmac);
342 channel->old_channel_key = NULL;
343 channel->old_hmac = NULL;
344 channel->rekey_task = NULL;
347 /* Saves channel key from encoded `key_payload'. This is used when we
348 receive Channel Key Payload and when we are processing JOIN command
351 void silc_client_save_channel_key(SilcClient client,
352 SilcClientConnection conn,
353 SilcBuffer key_payload,
354 SilcChannelEntry channel)
356 unsigned char *id_string, *key, *cipher, *hmac, hash[32];
359 SilcChannelKeyPayload payload;
361 payload = silc_channel_key_payload_parse(key_payload->data,
366 id_string = silc_channel_key_get_id(payload, &tmp_len);
368 silc_channel_key_payload_free(payload);
372 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
374 silc_channel_key_payload_free(payload);
380 channel = silc_client_get_channel_by_id(client, conn, id);
385 hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
388 /* Save the old key for a short period of time so that we can decrypt
389 channel message even after the rekey if some client would be sending
390 messages with the old key after the rekey. */
391 if (channel->old_channel_key)
392 silc_cipher_free(channel->old_channel_key);
393 if (channel->old_hmac)
394 silc_hmac_free(channel->old_hmac);
395 if (channel->rekey_task)
396 silc_schedule_task_del(client->schedule, channel->rekey_task);
397 channel->old_channel_key = channel->channel_key;
398 channel->old_hmac = channel->hmac;
399 channel->rekey_task =
400 silc_schedule_task_add(client->schedule, 0,
401 silc_client_save_channel_key_rekey, channel,
402 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
404 /* Free the old channel key data */
405 silc_free(channel->key);
408 key = silc_channel_key_get_key(payload, &tmp_len);
409 cipher = silc_channel_key_get_cipher(payload, NULL);
410 channel->key_len = tmp_len * 8;
411 channel->key = silc_memdup(key, tmp_len);
413 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
414 client->internal->ops->say(
416 SILC_CLIENT_MESSAGE_AUDIT,
417 "Cannot talk to channel: unsupported cipher %s",
422 /* Set the cipher key */
423 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
425 /* Generate HMAC key from the channel key data and set it */
426 silc_hmac_alloc(hmac, NULL, &channel->hmac);
427 silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
428 silc_hmac_set_key(channel->hmac, hash,
429 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
430 memset(hash, 0, sizeof(hash));
434 silc_channel_key_payload_free(payload);
437 /* Processes received key for channel. The received key will be used
438 to protect the traffic on the channel for now on. Client must receive
439 the key to the channel before talking on the channel is possible.
440 This is the key that server has generated, this is not the channel
441 private key, it is entirely local setting. */
443 void silc_client_receive_channel_key(SilcClient client,
444 SilcSocketConnection sock,
447 SILC_LOG_DEBUG(("Received key for channel"));
450 silc_client_save_channel_key(client, sock->user_data, packet, NULL);
453 /* Adds private key for channel. This may be set only if the channel's mode
454 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
455 mode is not set. When channel has private key then the messages are
456 encrypted using that key. All clients on the channel must also know the
457 key in order to decrypt the messages. However, it is possible to have
458 several private keys per one channel. In this case only some of the
459 clients on the channel may know the one key and only some the other key.
461 If `cipher' and/or `hmac' is NULL then default values will be used
462 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
464 The private key for channel is optional. If it is not set then the
465 channel messages are encrypted using the channel key generated by the
466 server. However, setting the private key (or keys) for the channel
467 significantly adds security. If more than one key is set the library
468 will automatically try all keys at the message decryption phase. Note:
469 setting many keys slows down the decryption phase as all keys has to
470 be tried in order to find the correct decryption key. However, setting
471 a few keys does not have big impact to the decryption performace.
473 NOTE: that this is entirely local setting. The key set using this function
474 is not sent to the network at any phase.
476 NOTE: If the key material was originated by the SKE protocol (using
477 silc_client_send_key_agreement) then the `key' MUST be the
478 key->send_enc_key as this is dictated by the SILC protocol. However,
479 currently it is not expected that the SKE key material would be used
480 as channel private key. However, this API allows it. */
482 bool silc_client_add_channel_private_key(SilcClient client,
483 SilcClientConnection conn,
484 SilcChannelEntry channel,
491 SilcChannelPrivateKey entry;
492 unsigned char hash[32];
493 SilcSKEKeyMaterial *keymat;
495 assert(client && channel);
497 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
501 cipher = SILC_DEFAULT_CIPHER;
503 hmac = SILC_DEFAULT_HMAC;
505 if (!silc_cipher_is_supported(cipher))
508 if (!silc_hmac_is_supported(hmac))
511 /* Produce the key material */
512 keymat = silc_calloc(1, sizeof(*keymat));
513 if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
514 client->md5hash, keymat)
515 != SILC_SKE_STATUS_OK)
518 /* Remove the current key, if it exists. */
519 if (channel->channel_key) {
520 silc_cipher_free(channel->channel_key);
521 memset(channel->key, 0, channel->key_len / 8);
522 silc_free(channel->key);
523 channel->channel_key = NULL;
525 channel->key_len = 0;
528 silc_hmac_free(channel->hmac);
529 channel->hmac = NULL;
532 if (!channel->private_keys)
533 channel->private_keys = silc_dlist_init();
536 entry = silc_calloc(1, sizeof(*entry));
537 entry->name = name ? strdup(name) : NULL;
538 entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
539 entry->key_len = keymat->enc_key_len / 8;
541 /* Allocate the cipher and set the key*/
542 silc_cipher_alloc(cipher, &entry->cipher);
543 silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
545 /* Generate HMAC key from the channel key data and set it */
546 silc_hmac_alloc(hmac, NULL, &entry->hmac);
547 silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key,
548 entry->key_len, hash);
549 silc_hmac_set_key(entry->hmac, hash,
550 silc_hash_len(silc_hmac_get_hash(entry->hmac)));
551 memset(hash, 0, sizeof(hash));
553 /* Add to the private keys list */
554 silc_dlist_add(channel->private_keys, entry);
556 if (!channel->curr_key)
557 channel->curr_key = entry;
559 /* Free the key material */
560 silc_ske_free_key_material(keymat);
565 /* Removes all private keys from the `channel'. The old channel key is used
566 after calling this to protect the channel messages. Returns FALSE on
567 on error, TRUE otherwise. */
569 bool silc_client_del_channel_private_keys(SilcClient client,
570 SilcClientConnection conn,
571 SilcChannelEntry channel)
573 SilcChannelPrivateKey entry;
575 assert(client && channel);
577 if (!channel->private_keys)
580 silc_dlist_start(channel->private_keys);
581 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
582 silc_dlist_del(channel->private_keys, entry);
583 memset(entry->key, 0, entry->key_len);
584 silc_free(entry->key);
585 silc_free(entry->name);
586 silc_cipher_free(entry->cipher);
587 silc_hmac_free(entry->hmac);
591 channel->curr_key = NULL;
593 silc_dlist_uninit(channel->private_keys);
594 channel->private_keys = NULL;
599 /* Removes and frees private key `key' from the channel `channel'. The `key'
600 is retrieved by calling the function silc_client_list_channel_private_keys.
601 The key is not used after this. If the key was last private key then the
602 old channel key is used hereafter to protect the channel messages. This
603 returns FALSE on error, TRUE otherwise. */
605 bool silc_client_del_channel_private_key(SilcClient client,
606 SilcClientConnection conn,
607 SilcChannelEntry channel,
608 SilcChannelPrivateKey key)
610 SilcChannelPrivateKey entry;
612 assert(client && channel);
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 assert(client && channel);
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 assert(client && channel);
694 channel->curr_key = key;
697 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the
698 channel indicated by the `channel'. NULL if client is not joined on
701 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
702 SilcClientEntry client_entry)
706 if (silc_hash_table_find(channel->user_list, client_entry, NULL,