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 "clientlibincludes.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,
45 SilcSocketConnection sock = conn->sock;
47 SilcPacketContext packetdata;
50 unsigned char *id_string;
54 SILC_LOG_DEBUG(("Sending packet to channel"));
56 /* Take the key to be used */
57 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
59 /* Use key application specified */
62 } else if (channel->curr_key) {
63 /* Use current private key */
64 cipher = channel->curr_key->cipher;
65 hmac = channel->curr_key->hmac;
66 } else if (!channel->curr_key && channel->private_keys) {
67 /* Use just some private key since we don't know what to use
68 and private keys are set. */
69 silc_dlist_start(channel->private_keys);
70 key = silc_dlist_get(channel->private_keys);
74 /* Use this key as current private key */
75 channel->curr_key = key;
77 /* Use normal channel key generated by the server */
78 cipher = channel->channel_key;
82 /* Use normal channel key generated by the server */
83 cipher = channel->channel_key;
90 block_len = silc_cipher_get_block_len(cipher);
93 iv_len = silc_cipher_get_block_len(cipher);
94 if (channel->iv[0] == '\0')
95 for (i = 0; i < iv_len; i++) channel->iv[i] =
96 silc_rng_get_byte(client->rng);
98 silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
100 /* Encode the channel payload. This also encrypts the message payload. */
101 payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len,
102 channel->iv, cipher, hmac);
104 /* Get data used in packet header encryption, keys and stuff. */
105 cipher = conn->send_key;
106 hmac = conn->hmac_send;
107 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
109 /* Set the packet context pointers. The destination ID is always
110 the Channel ID of the channel. Server and router will handle the
111 distribution of the packet. */
112 packetdata.flags = 0;
113 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
114 packetdata.src_id = conn->local_id_data;
115 packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
116 packetdata.src_id_type = SILC_ID_CLIENT;
117 packetdata.dst_id = id_string;
118 packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
119 packetdata.dst_id_type = SILC_ID_CHANNEL;
120 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
121 packetdata.src_id_len + packetdata.dst_id_len;
122 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
123 packetdata.src_id_len +
124 packetdata.dst_id_len), block_len);
126 /* Prepare outgoing data buffer for packet sending */
127 silc_packet_send_prepare(sock,
128 SILC_PACKET_HEADER_LEN +
129 packetdata.src_id_len +
130 packetdata.dst_id_len,
134 packetdata.buffer = sock->outbuf;
136 /* Put the channel message payload to the outgoing data buffer */
137 silc_buffer_put(sock->outbuf, payload->data, payload->len);
139 /* Create the outgoing packet */
140 silc_packet_assemble(&packetdata, cipher);
142 /* Encrypt the header and padding of the packet. This is encrypted
143 with normal session key shared with our server. */
144 silc_packet_encrypt(cipher, hmac, conn->psn_send++,
145 sock->outbuf, SILC_PACKET_HEADER_LEN +
146 packetdata.src_id_len + packetdata.dst_id_len +
149 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
150 sock->outbuf->data, sock->outbuf->len);
152 /* Now actually send the packet */
153 silc_client_packet_send_real(client, sock, force_send);
154 silc_buffer_free(payload);
155 silc_free(id_string);
158 static void silc_client_channel_message_cb(SilcClient client,
159 SilcClientConnection conn,
160 SilcClientEntry *clients,
161 uint32 clients_count,
164 SilcPacketContext *packet = (SilcPacketContext *)context;
167 silc_client_channel_message(client, conn->sock, packet);
168 silc_packet_context_free(packet);
171 /* Process received message to a channel (or from a channel, really). This
172 decrypts the channel message with channel specific key and parses the
173 channel payload. Finally it displays the message on the screen. */
175 void silc_client_channel_message(SilcClient client,
176 SilcSocketConnection sock,
177 SilcPacketContext *packet)
179 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
180 SilcBuffer buffer = packet->buffer;
181 SilcChannelMessagePayload payload = NULL;
182 SilcChannelID *id = NULL;
183 SilcChannelEntry channel;
185 SilcIDCacheEntry id_cache = NULL;
186 SilcClientID *client_id = NULL;
188 unsigned char *message;
190 SILC_LOG_DEBUG(("Start"));
193 if (packet->dst_id_type != SILC_ID_CHANNEL)
196 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
200 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
204 /* Find the channel entry from channels on this connection */
205 if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id, &id_cache))
208 channel = (SilcChannelEntry)id_cache->context;
210 /* If there is no channel private key then just decrypt the message
211 with the channel key. If private keys are set then just go through
212 all private keys and check what decrypts correctly. */
213 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
214 /* Parse the channel message payload. This also decrypts the payload */
215 payload = silc_channel_message_payload_parse(buffer, channel->channel_key,
218 /* If decryption failed and we have just performed channel key rekey
219 we will use the old key in decryption. If that fails too then we
220 cannot do more and will drop the packet. */
222 if (!channel->old_channel_key)
225 payload = silc_channel_message_payload_parse(buffer,
226 channel->old_channel_key,
231 } else if (channel->private_keys) {
232 SilcChannelPrivateKey entry;
234 silc_dlist_start(channel->private_keys);
235 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
236 /* Parse the channel message payload. This also decrypts the payload */
237 payload = silc_channel_message_payload_parse(buffer, entry->cipher,
242 if (entry == SILC_LIST_END)
248 /* Find client entry */
249 silc_list_start(channel->clients);
250 while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
251 if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id) &&
252 chu->client->nickname) {
259 /* Resolve the client info */
260 silc_client_get_client_by_id_resolve(client, conn, client_id,
261 silc_client_channel_message_cb,
262 silc_packet_context_dup(packet));
266 message = silc_channel_message_get_data(payload, NULL);
268 /* Pass the message to application */
269 client->ops->channel_message(client, conn, chu->client, channel,
270 silc_channel_message_get_flags(payload),
277 silc_free(client_id);
279 silc_channel_message_payload_free(payload);
282 /* Timeout callback that is called after a short period of time after the
283 new channel key has been created. This removes the old channel key all
286 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
288 SilcChannelEntry channel = (SilcChannelEntry)context;
290 if (channel->old_channel_key)
291 silc_cipher_free(channel->old_channel_key);
292 if (channel->old_hmac)
293 silc_hmac_free(channel->old_hmac);
294 channel->old_channel_key = NULL;
295 channel->old_hmac = NULL;
296 channel->rekey_task = NULL;
299 /* Saves channel key from encoded `key_payload'. This is used when we
300 receive Channel Key Payload and when we are processing JOIN command
303 void silc_client_save_channel_key(SilcClientConnection conn,
304 SilcBuffer key_payload,
305 SilcChannelEntry channel)
307 unsigned char *id_string, *key, *cipher, *hmac, hash[32];
310 SilcIDCacheEntry id_cache = NULL;
311 SilcChannelKeyPayload payload;
313 payload = silc_channel_key_payload_parse(key_payload);
317 id_string = silc_channel_key_get_id(payload, &tmp_len);
319 silc_channel_key_payload_free(payload);
323 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
325 silc_channel_key_payload_free(payload);
331 if (!silc_idcache_find_by_id_one(conn->channel_cache,
332 (void *)id, &id_cache))
335 /* Get channel entry */
336 channel = (SilcChannelEntry)id_cache->context;
339 hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
342 /* Save the old key for a short period of time so that we can decrypt
343 channel message even after the rekey if some client would be sending
344 messages with the old key after the rekey. */
345 if (channel->old_channel_key)
346 silc_cipher_free(channel->old_channel_key);
347 if (channel->old_hmac)
348 silc_hmac_free(channel->old_hmac);
349 if (channel->rekey_task)
350 silc_schedule_task_del(conn->client->schedule, channel->rekey_task);
351 channel->old_channel_key = channel->channel_key;
352 channel->old_hmac = channel->hmac;
353 channel->rekey_task =
354 silc_schedule_task_add(conn->client->schedule, 0,
355 silc_client_save_channel_key_rekey, channel,
356 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
358 /* Free the old channel key data */
359 silc_free(channel->key);
362 key = silc_channel_key_get_key(payload, &tmp_len);
363 cipher = silc_channel_key_get_cipher(payload, NULL);
364 channel->key_len = tmp_len * 8;
365 channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
366 memcpy(channel->key, key, tmp_len);
368 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
369 conn->client->ops->say(conn->client, conn, SILC_CLIENT_MESSAGE_AUDIT,
370 "Cannot talk to channel: unsupported cipher %s",
375 /* Set the cipher key */
376 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
378 /* Generate HMAC key from the channel key data and set it */
379 silc_hmac_alloc(hmac, NULL, &channel->hmac);
380 silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
381 silc_hmac_set_key(channel->hmac, hash,
382 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
383 memset(hash, 0, sizeof(hash));
387 silc_channel_key_payload_free(payload);
390 /* Processes received key for channel. The received key will be used
391 to protect the traffic on the channel for now on. Client must receive
392 the key to the channel before talking on the channel is possible.
393 This is the key that server has generated, this is not the channel
394 private key, it is entirely local setting. */
396 void silc_client_receive_channel_key(SilcClient client,
397 SilcSocketConnection sock,
400 SILC_LOG_DEBUG(("Received key for channel"));
403 silc_client_save_channel_key(sock->user_data, packet, NULL);
406 /* Adds private key for channel. This may be set only if the channel's mode
407 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
408 mode is not set. When channel has private key then the messages are
409 encrypted using that key. All clients on the channel must also know the
410 key in order to decrypt the messages. However, it is possible to have
411 several private keys per one channel. In this case only some of the
412 clients on the channel may know the one key and only some the other key.
414 If `cipher' and/or `hmac' is NULL then default values will be used
415 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
417 The private key for channel is optional. If it is not set then the
418 channel messages are encrypted using the channel key generated by the
419 server. However, setting the private key (or keys) for the channel
420 significantly adds security. If more than one key is set the library
421 will automatically try all keys at the message decryption phase. Note:
422 setting many keys slows down the decryption phase as all keys has to
423 be tried in order to find the correct decryption key. However, setting
424 a few keys does not have big impact to the decryption performace.
426 NOTE: that this is entirely local setting. The key set using this function
427 is not sent to the network at any phase.
429 NOTE: If the key material was originated by the SKE protocol (using
430 silc_client_send_key_agreement) then the `key' MUST be the
431 key->send_enc_key as this is dictated by the SILC protocol. However,
432 currently it is not expected that the SKE key material would be used
433 as channel private key. However, this API allows it. */
435 int silc_client_add_channel_private_key(SilcClient client,
436 SilcClientConnection conn,
437 SilcChannelEntry channel,
443 SilcChannelPrivateKey entry;
444 unsigned char hash[32];
445 SilcSKEKeyMaterial *keymat;
447 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
451 cipher = SILC_DEFAULT_CIPHER;
453 hmac = SILC_DEFAULT_HMAC;
455 if (!silc_cipher_is_supported(cipher))
458 if (!silc_hmac_is_supported(hmac))
461 /* Produce the key material */
462 keymat = silc_calloc(1, sizeof(*keymat));
463 if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
464 client->md5hash, keymat)
465 != SILC_SKE_STATUS_OK)
468 /* Remove the current key, if it exists. */
469 if (channel->channel_key) {
470 silc_cipher_free(channel->channel_key);
471 memset(channel->key, 0, channel->key_len / 8);
472 silc_free(channel->key);
473 channel->channel_key = NULL;
475 channel->key_len = 0;
478 silc_hmac_free(channel->hmac);
479 channel->hmac = NULL;
482 if (!channel->private_keys)
483 channel->private_keys = silc_dlist_init();
486 entry = silc_calloc(1, sizeof(*entry));
487 entry->key = silc_calloc(keymat->enc_key_len / 8, sizeof(*entry->key));
488 memcpy(entry->key, keymat->send_enc_key, keymat->enc_key_len / 8);
489 entry->key_len = keymat->enc_key_len / 8;
491 /* Allocate the cipher and set the key*/
492 silc_cipher_alloc(cipher, &entry->cipher);
493 silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
495 /* Generate HMAC key from the channel key data and set it */
496 silc_hmac_alloc(hmac, NULL, &entry->hmac);
497 silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key,
498 entry->key_len, hash);
499 silc_hmac_set_key(entry->hmac, hash,
500 silc_hash_len(silc_hmac_get_hash(entry->hmac)));
501 memset(hash, 0, sizeof(hash));
503 /* Add to the private keys list */
504 silc_dlist_add(channel->private_keys, entry);
506 if (!channel->curr_key)
507 channel->curr_key = entry;
509 /* Free the key material */
510 silc_ske_free_key_material(keymat);
515 /* Removes all private keys from the `channel'. The old channel key is used
516 after calling this to protect the channel messages. Returns FALSE on
517 on error, TRUE otherwise. */
519 int silc_client_del_channel_private_keys(SilcClient client,
520 SilcClientConnection conn,
521 SilcChannelEntry channel)
523 SilcChannelPrivateKey entry;
525 if (!channel->private_keys)
528 silc_dlist_start(channel->private_keys);
529 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
530 silc_dlist_del(channel->private_keys, entry);
531 memset(entry->key, 0, entry->key_len);
532 silc_free(entry->key);
533 silc_cipher_free(entry->cipher);
534 silc_hmac_free(entry->hmac);
538 channel->curr_key = NULL;
540 silc_dlist_uninit(channel->private_keys);
541 channel->private_keys = NULL;
546 /* Removes and frees private key `key' from the channel `channel'. The `key'
547 is retrieved by calling the function silc_client_list_channel_private_keys.
548 The key is not used after this. If the key was last private key then the
549 old channel key is used hereafter to protect the channel messages. This
550 returns FALSE on error, TRUE otherwise. */
552 int silc_client_del_channel_private_key(SilcClient client,
553 SilcClientConnection conn,
554 SilcChannelEntry channel,
555 SilcChannelPrivateKey key)
557 SilcChannelPrivateKey entry;
559 if (!channel->private_keys)
562 silc_dlist_start(channel->private_keys);
563 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
565 if (channel->curr_key == entry)
566 channel->curr_key = NULL;
568 silc_dlist_del(channel->private_keys, entry);
569 memset(entry->key, 0, entry->key_len);
570 silc_free(entry->key);
571 silc_cipher_free(entry->cipher);
572 silc_hmac_free(entry->hmac);
575 if (silc_dlist_count(channel->private_keys) == 0) {
576 silc_dlist_uninit(channel->private_keys);
577 channel->private_keys = NULL;
587 /* Returns array (pointers) of private keys associated to the `channel'.
588 The caller must free the array by calling the function
589 silc_client_free_channel_private_keys. The pointers in the array may be
590 used to delete the specific key by giving the pointer as argument to the
591 function silc_client_del_channel_private_key. */
593 SilcChannelPrivateKey *
594 silc_client_list_channel_private_keys(SilcClient client,
595 SilcClientConnection conn,
596 SilcChannelEntry channel,
599 SilcChannelPrivateKey *keys = NULL, entry;
602 if (!channel->private_keys)
605 silc_dlist_start(channel->private_keys);
606 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
607 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
618 /* Frees the SilcChannelPrivateKey array. */
620 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,