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;
53 SILC_LOG_DEBUG(("Sending packet to channel"));
55 /* Take the key to be used */
56 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
58 /* Use key application specified */
61 } else if (channel->curr_key) {
62 /* Use current private key */
63 cipher = channel->curr_key->cipher;
64 hmac = channel->curr_key->hmac;
65 } else if (!channel->curr_key && channel->private_keys) {
66 /* Use just some private key since we don't know what to use
67 and private keys are set. */
68 silc_dlist_start(channel->private_keys);
69 key = silc_dlist_get(channel->private_keys);
73 /* Use this key as current private key */
74 channel->curr_key = key;
76 /* Use normal channel key generated by the server */
77 cipher = channel->channel_key;
81 /* Use normal channel key generated by the server */
82 cipher = channel->channel_key;
90 iv_len = silc_cipher_get_block_len(cipher);
91 if (channel->iv[0] == '\0')
92 for (i = 0; i < iv_len; i++) channel->iv[i] =
93 silc_rng_get_byte(client->rng);
95 silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
97 /* Encode the channel payload. This also encrypts the message payload. */
98 payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len,
99 channel->iv, cipher, hmac);
101 /* Get data used in packet header encryption, keys and stuff. */
102 cipher = conn->send_key;
103 hmac = conn->hmac_send;
104 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
106 /* Set the packet context pointers. The destination ID is always
107 the Channel ID of the channel. Server and router will handle the
108 distribution of the packet. */
109 packetdata.flags = 0;
110 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
111 packetdata.src_id = conn->local_id_data;
112 packetdata.src_id_len = silc_id_get_len(conn->local_id, SILC_ID_CLIENT);
113 packetdata.src_id_type = SILC_ID_CLIENT;
114 packetdata.dst_id = id_string;
115 packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
116 packetdata.dst_id_type = SILC_ID_CHANNEL;
117 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
118 packetdata.src_id_len + packetdata.dst_id_len;
119 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
120 packetdata.src_id_len +
121 packetdata.dst_id_len));
123 /* Prepare outgoing data buffer for packet sending */
124 silc_packet_send_prepare(sock,
125 SILC_PACKET_HEADER_LEN +
126 packetdata.src_id_len +
127 packetdata.dst_id_len,
131 packetdata.buffer = sock->outbuf;
133 /* Put the channel message payload to the outgoing data buffer */
134 silc_buffer_put(sock->outbuf, payload->data, payload->len);
136 /* Create the outgoing packet */
137 silc_packet_assemble(&packetdata);
139 /* Encrypt the header and padding of the packet. This is encrypted
140 with normal session key shared with our server. */
141 silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN +
142 packetdata.src_id_len + packetdata.dst_id_len +
145 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
146 sock->outbuf->data, sock->outbuf->len);
148 /* Now actually send the packet */
149 silc_client_packet_send_real(client, sock, force_send);
150 silc_buffer_free(payload);
151 silc_free(id_string);
154 static void silc_client_channel_message_cb(SilcClient client,
155 SilcClientConnection conn,
156 SilcClientEntry *clients,
157 uint32 clients_count,
160 SilcPacketContext *packet = (SilcPacketContext *)context;
163 silc_client_channel_message(client, conn->sock, packet);
164 silc_packet_context_free(packet);
167 /* Process received message to a channel (or from a channel, really). This
168 decrypts the channel message with channel specific key and parses the
169 channel payload. Finally it displays the message on the screen. */
171 void silc_client_channel_message(SilcClient client,
172 SilcSocketConnection sock,
173 SilcPacketContext *packet)
175 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
176 SilcBuffer buffer = packet->buffer;
177 SilcChannelMessagePayload payload = NULL;
178 SilcChannelID *id = NULL;
179 SilcChannelEntry channel;
181 SilcIDCacheEntry id_cache = NULL;
182 SilcClientID *client_id = NULL;
184 unsigned char *message;
186 SILC_LOG_DEBUG(("Start"));
189 if (packet->dst_id_type != SILC_ID_CHANNEL)
192 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
196 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
200 /* Find the channel entry from channels on this connection */
201 if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id, &id_cache))
204 channel = (SilcChannelEntry)id_cache->context;
206 /* If there is no channel private key then just decrypt the message
207 with the channel key. If private keys are set then just go through
208 all private keys and check what decrypts correctly. */
209 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
210 /* Parse the channel message payload. This also decrypts the payload */
211 payload = silc_channel_message_payload_parse(buffer, channel->channel_key,
214 /* If decryption failed and we have just performed channel key rekey
215 we will use the old key in decryption. If that fails too then we
216 cannot do more and will drop the packet. */
218 if (!channel->old_channel_key)
221 payload = silc_channel_message_payload_parse(buffer,
222 channel->old_channel_key,
227 } else if (channel->private_keys) {
228 SilcChannelPrivateKey entry;
230 silc_dlist_start(channel->private_keys);
231 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
232 /* Parse the channel message payload. This also decrypts the payload */
233 payload = silc_channel_message_payload_parse(buffer, entry->cipher,
238 if (entry == SILC_LIST_END)
244 /* Find client entry */
245 silc_list_start(channel->clients);
246 while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
247 if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id)) {
254 /* Resolve the client info */
255 silc_client_get_client_by_id_resolve(client, conn, client_id,
256 silc_client_channel_message_cb,
257 silc_packet_context_dup(packet));
261 message = silc_channel_message_get_data(payload, NULL);
263 /* Pass the message to application */
264 client->ops->channel_message(client, conn, chu->client, channel,
265 silc_channel_message_get_flags(payload),
272 silc_free(client_id);
274 silc_channel_message_payload_free(payload);
277 /* Timeout callback that is called after a short period of time after the
278 new channel key has been created. This removes the old channel key all
281 SILC_TASK_CALLBACK(silc_client_save_channel_key_rekey)
283 SilcChannelEntry channel = (SilcChannelEntry)context;
285 if (channel->old_channel_key)
286 silc_cipher_free(channel->old_channel_key);
287 if (channel->old_hmac)
288 silc_hmac_free(channel->old_hmac);
289 channel->old_channel_key = NULL;
290 channel->old_hmac = NULL;
291 channel->rekey_task = NULL;
294 /* Saves channel key from encoded `key_payload'. This is used when we
295 receive Channel Key Payload and when we are processing JOIN command
298 void silc_client_save_channel_key(SilcClientConnection conn,
299 SilcBuffer key_payload,
300 SilcChannelEntry channel)
302 unsigned char *id_string, *key, *cipher, *hmac, hash[32];
305 SilcIDCacheEntry id_cache = NULL;
306 SilcChannelKeyPayload payload;
308 payload = silc_channel_key_payload_parse(key_payload);
312 id_string = silc_channel_key_get_id(payload, &tmp_len);
314 silc_channel_key_payload_free(payload);
318 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
320 silc_channel_key_payload_free(payload);
326 if (!silc_idcache_find_by_id_one(conn->channel_cache,
327 (void *)id, &id_cache))
330 /* Get channel entry */
331 channel = (SilcChannelEntry)id_cache->context;
334 hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
337 /* Save the old key for a short period of time so that we can decrypt
338 channel message even after the rekey if some client would be sending
339 messages with the old key after the rekey. */
340 if (channel->old_channel_key)
341 silc_cipher_free(channel->old_channel_key);
342 if (channel->old_hmac)
343 silc_hmac_free(channel->old_hmac);
344 if (channel->rekey_task)
345 silc_schedule_task_del(conn->client->schedule, channel->rekey_task);
346 channel->old_channel_key = channel->channel_key;
347 channel->old_hmac = channel->hmac;
348 channel->rekey_task =
349 silc_schedule_task_add(conn->client->schedule, 0,
350 silc_client_save_channel_key_rekey, channel,
351 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
353 /* Free the old channel key data */
354 silc_free(channel->key);
357 key = silc_channel_key_get_key(payload, &tmp_len);
358 cipher = silc_channel_key_get_cipher(payload, NULL);
359 channel->key_len = tmp_len * 8;
360 channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
361 memcpy(channel->key, key, tmp_len);
363 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
364 conn->client->ops->say(conn->client, conn, SILC_CLIENT_MESSAGE_AUDIT,
365 "Cannot talk to channel: unsupported cipher %s",
370 /* Set the cipher key */
371 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
373 /* Generate HMAC key from the channel key data and set it */
374 silc_hmac_alloc(hmac, NULL, &channel->hmac);
375 silc_hash_make(silc_hmac_get_hash(channel->hmac), key, tmp_len, hash);
376 silc_hmac_set_key(channel->hmac, hash,
377 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
378 memset(hash, 0, sizeof(hash));
382 silc_channel_key_payload_free(payload);
385 /* Processes received key for channel. The received key will be used
386 to protect the traffic on the channel for now on. Client must receive
387 the key to the channel before talking on the channel is possible.
388 This is the key that server has generated, this is not the channel
389 private key, it is entirely local setting. */
391 void silc_client_receive_channel_key(SilcClient client,
392 SilcSocketConnection sock,
395 SILC_LOG_DEBUG(("Received key for channel"));
398 silc_client_save_channel_key(sock->user_data, packet, NULL);
401 /* Adds private key for channel. This may be set only if the channel's mode
402 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
403 mode is not set. When channel has private key then the messages are
404 encrypted using that key. All clients on the channel must also know the
405 key in order to decrypt the messages. However, it is possible to have
406 several private keys per one channel. In this case only some of the
407 clients on the channel may know the one key and only some the other key.
409 If `cipher' and/or `hmac' is NULL then default values will be used
410 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
412 The private key for channel is optional. If it is not set then the
413 channel messages are encrypted using the channel key generated by the
414 server. However, setting the private key (or keys) for the channel
415 significantly adds security. If more than one key is set the library
416 will automatically try all keys at the message decryption phase. Note:
417 setting many keys slows down the decryption phase as all keys has to
418 be tried in order to find the correct decryption key. However, setting
419 a few keys does not have big impact to the decryption performace.
421 NOTE: that this is entirely local setting. The key set using this function
422 is not sent to the network at any phase.
424 NOTE: If the key material was originated by the SKE protocol (using
425 silc_client_send_key_agreement) then the `key' MUST be the
426 key->send_enc_key as this is dictated by the SILC protocol. However,
427 currently it is not expected that the SKE key material would be used
428 as channel private key. However, this API allows it. */
430 int silc_client_add_channel_private_key(SilcClient client,
431 SilcClientConnection conn,
432 SilcChannelEntry channel,
438 SilcChannelPrivateKey entry;
439 unsigned char hash[32];
440 SilcSKEKeyMaterial *keymat;
442 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
446 cipher = SILC_DEFAULT_CIPHER;
448 hmac = SILC_DEFAULT_HMAC;
450 if (!silc_cipher_is_supported(cipher))
453 if (!silc_hmac_is_supported(hmac))
456 /* Produce the key material */
457 keymat = silc_calloc(1, sizeof(*keymat));
458 if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
459 client->md5hash, keymat)
460 != SILC_SKE_STATUS_OK)
463 /* Remove the current key, if it exists. */
464 if (channel->channel_key) {
465 silc_cipher_free(channel->channel_key);
466 memset(channel->key, 0, channel->key_len / 8);
467 silc_free(channel->key);
468 channel->channel_key = NULL;
470 channel->key_len = 0;
473 silc_hmac_free(channel->hmac);
474 channel->hmac = NULL;
477 if (!channel->private_keys)
478 channel->private_keys = silc_dlist_init();
481 entry = silc_calloc(1, sizeof(*entry));
482 entry->key = silc_calloc(keymat->enc_key_len / 8, sizeof(*entry->key));
483 memcpy(entry->key, keymat->send_enc_key, keymat->enc_key_len / 8);
484 entry->key_len = keymat->enc_key_len / 8;
486 /* Allocate the cipher and set the key*/
487 silc_cipher_alloc(cipher, &entry->cipher);
488 silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
490 /* Generate HMAC key from the channel key data and set it */
491 silc_hmac_alloc(hmac, NULL, &entry->hmac);
492 silc_hash_make(silc_hmac_get_hash(entry->hmac), entry->key,
493 entry->key_len, hash);
494 silc_hmac_set_key(entry->hmac, hash,
495 silc_hash_len(silc_hmac_get_hash(entry->hmac)));
496 memset(hash, 0, sizeof(hash));
498 /* Add to the private keys list */
499 silc_dlist_add(channel->private_keys, entry);
501 if (!channel->curr_key)
502 channel->curr_key = entry;
504 /* Free the key material */
505 silc_ske_free_key_material(keymat);
510 /* Removes all private keys from the `channel'. The old channel key is used
511 after calling this to protect the channel messages. Returns FALSE on
512 on error, TRUE otherwise. */
514 int silc_client_del_channel_private_keys(SilcClient client,
515 SilcClientConnection conn,
516 SilcChannelEntry channel)
518 SilcChannelPrivateKey entry;
520 if (!channel->private_keys)
523 silc_dlist_start(channel->private_keys);
524 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
525 silc_dlist_del(channel->private_keys, entry);
526 memset(entry->key, 0, entry->key_len);
527 silc_free(entry->key);
528 silc_cipher_free(entry->cipher);
529 silc_hmac_free(entry->hmac);
533 channel->curr_key = NULL;
535 silc_dlist_uninit(channel->private_keys);
536 channel->private_keys = NULL;
541 /* Removes and frees private key `key' from the channel `channel'. The `key'
542 is retrieved by calling the function silc_client_list_channel_private_keys.
543 The key is not used after this. If the key was last private key then the
544 old channel key is used hereafter to protect the channel messages. This
545 returns FALSE on error, TRUE otherwise. */
547 int silc_client_del_channel_private_key(SilcClient client,
548 SilcClientConnection conn,
549 SilcChannelEntry channel,
550 SilcChannelPrivateKey key)
552 SilcChannelPrivateKey entry;
554 if (!channel->private_keys)
557 silc_dlist_start(channel->private_keys);
558 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
560 if (channel->curr_key == entry)
561 channel->curr_key = NULL;
563 silc_dlist_del(channel->private_keys, entry);
564 memset(entry->key, 0, entry->key_len);
565 silc_free(entry->key);
566 silc_cipher_free(entry->cipher);
567 silc_hmac_free(entry->hmac);
570 if (silc_dlist_count(channel->private_keys) == 0) {
571 silc_dlist_uninit(channel->private_keys);
572 channel->private_keys = NULL;
582 /* Returns array (pointers) of private keys associated to the `channel'.
583 The caller must free the array by calling the function
584 silc_client_free_channel_private_keys. The pointers in the array may be
585 used to delete the specific key by giving the pointer as argument to the
586 function silc_client_del_channel_private_key. */
588 SilcChannelPrivateKey *
589 silc_client_list_channel_private_keys(SilcClient client,
590 SilcClientConnection conn,
591 SilcChannelEntry channel,
594 SilcChannelPrivateKey *keys = NULL, entry;
597 if (!channel->private_keys)
600 silc_dlist_start(channel->private_keys);
601 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
602 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
613 /* Frees the SilcChannelPrivateKey array. */
615 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,