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,
41 unsigned int data_len,
45 SilcSocketConnection sock = conn->sock;
47 SilcPacketContext packetdata;
50 unsigned char *id_string;
53 SILC_LOG_DEBUG(("Sending packet to channel"));
55 if (!channel || !channel->hmac ||
56 (!channel->channel_key && !key && !channel->private_keys)) {
57 client->ops->say(client, conn,
58 "Cannot talk to channel: key does not exist");
62 /* Take the key to be used */
63 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
65 /* Use key application specified */
68 } else if (channel->curr_key) {
69 /* Use current private key */
70 cipher = channel->curr_key->cipher;
71 hmac = channel->curr_key->hmac;
72 } else if (!channel->curr_key && channel->private_keys) {
73 /* Use just some private key since we don't know what to use
74 and private keys are set. */
75 silc_dlist_start(channel->private_keys);
76 key = silc_dlist_get(channel->private_keys);
80 /* Use this key as current private key */
81 channel->curr_key = key;
83 /* Use normal channel key generated by the server */
84 cipher = channel->channel_key;
88 /* Use normal channel key generated by the server */
89 cipher = channel->channel_key;
94 iv_len = silc_cipher_get_block_len(cipher);
95 if (channel->iv[0] == '\0')
96 for (i = 0; i < iv_len; i++) channel->iv[i] =
97 silc_rng_get_byte(client->rng);
99 silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
101 /* Encode the channel payload. This also encrypts the message payload. */
102 payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len,
103 channel->iv, cipher, hmac);
105 /* Get data used in packet header encryption, keys and stuff. */
106 cipher = conn->send_key;
108 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
110 /* Set the packet context pointers. The destination ID is always
111 the Channel ID of the channel. Server and router will handle the
112 distribution of the packet. */
113 packetdata.flags = 0;
114 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
115 packetdata.src_id = conn->local_id_data;
116 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
117 packetdata.src_id_type = SILC_ID_CLIENT;
118 packetdata.dst_id = id_string;
119 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
120 packetdata.dst_id_type = SILC_ID_CHANNEL;
121 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
122 packetdata.src_id_len + packetdata.dst_id_len;
123 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
124 packetdata.src_id_len +
125 packetdata.dst_id_len));
127 /* Prepare outgoing data buffer for packet sending */
128 silc_packet_send_prepare(sock,
129 SILC_PACKET_HEADER_LEN +
130 packetdata.src_id_len +
131 packetdata.dst_id_len,
135 packetdata.buffer = sock->outbuf;
137 /* Put the channel message payload to the outgoing data buffer */
138 silc_buffer_put(sock->outbuf, payload->data, payload->len);
140 /* Create the outgoing packet */
141 silc_packet_assemble(&packetdata);
143 /* Encrypt the header and padding of the packet. This is encrypted
144 with normal session key shared with our server. */
145 silc_packet_encrypt(cipher, hmac, 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 /* Process received message to a channel (or from a channel, really). This
159 decrypts the channel message with channel specific key and parses the
160 channel payload. Finally it displays the message on the screen. */
162 void silc_client_channel_message(SilcClient client,
163 SilcSocketConnection sock,
164 SilcPacketContext *packet)
166 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
167 SilcBuffer buffer = packet->buffer;
168 SilcChannelMessagePayload payload = NULL;
169 SilcChannelID *id = NULL;
170 SilcChannelEntry channel;
172 SilcIDCacheEntry id_cache = NULL;
173 SilcClientID *client_id = NULL;
175 unsigned char *message;
177 SILC_LOG_DEBUG(("Start"));
180 if (packet->dst_id_type != SILC_ID_CHANNEL)
183 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
187 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
191 /* Find the channel entry from channels on this connection */
192 if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
193 SILC_ID_CHANNEL, &id_cache))
196 channel = (SilcChannelEntry)id_cache->context;
198 /* If there is no channel private key then just decrypt the message
199 with the channel key. If private keys are set then just go through
200 all private keys and check what decrypts correctly. */
201 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
202 /* Parse the channel message payload. This also decrypts the payload */
203 payload = silc_channel_message_payload_parse(buffer, channel->channel_key,
207 } else if (channel->private_keys) {
208 SilcChannelPrivateKey entry;
210 silc_dlist_start(channel->private_keys);
211 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
212 /* Parse the channel message payload. This also decrypts the payload */
213 payload = silc_channel_message_payload_parse(buffer, entry->cipher,
218 if (entry == SILC_LIST_END)
224 message = silc_channel_message_get_data(payload, NULL);
226 /* Find client entry */
227 silc_list_start(channel->clients);
228 while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
229 if (!SILC_ID_CLIENT_COMPARE(chu->client->id, client_id)) {
235 /* Pass the message to application */
236 client->ops->channel_message(client, conn, found ? chu->client : NULL,
238 silc_channel_message_get_flags(payload),
245 silc_free(client_id);
247 silc_channel_message_payload_free(payload);
250 /* Saves channel key from encoded `key_payload'. This is used when we
251 receive Channel Key Payload and when we are processing JOIN command
254 void silc_client_save_channel_key(SilcClientConnection conn,
255 SilcBuffer key_payload,
256 SilcChannelEntry channel)
258 unsigned char *id_string, *key, *cipher, hash[32];
259 unsigned int tmp_len;
261 SilcIDCacheEntry id_cache = NULL;
262 SilcChannelKeyPayload payload;
264 payload = silc_channel_key_payload_parse(key_payload);
268 id_string = silc_channel_key_get_id(payload, &tmp_len);
270 silc_channel_key_payload_free(payload);
274 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
276 silc_channel_key_payload_free(payload);
282 if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id,
283 SILC_ID_CHANNEL, &id_cache))
286 /* Get channel entry */
287 channel = (SilcChannelEntry)id_cache->context;
291 key = silc_channel_key_get_key(payload, &tmp_len);
292 cipher = silc_channel_key_get_cipher(payload, NULL);
293 channel->key_len = tmp_len * 8;
294 channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
295 memcpy(channel->key, key, tmp_len);
297 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
298 conn->client->ops->say(conn->client, conn,
299 "Cannot talk to channel: unsupported cipher %s", cipher);
303 /* Set the cipher key */
304 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
306 /* Generate HMAC key from the channel key data and set it */
308 silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
309 silc_hash_make(channel->hmac->hash, key, tmp_len, hash);
310 silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
311 memset(hash, 0, sizeof(hash));
313 /* Client is now joined to the channel */
314 channel->on_channel = TRUE;
318 silc_channel_key_payload_free(payload);
321 /* Processes received key for channel. The received key will be used
322 to protect the traffic on the channel for now on. Client must receive
323 the key to the channel before talking on the channel is possible.
324 This is the key that server has generated, this is not the channel
325 private key, it is entirely local setting. */
327 void silc_client_receive_channel_key(SilcClient client,
328 SilcSocketConnection sock,
331 SILC_LOG_DEBUG(("Received key for channel"));
334 silc_client_save_channel_key(sock->user_data, packet, NULL);
337 /* Adds private key for channel. This may be set only if the channel's mode
338 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
339 mode is not set. When channel has private key then the messages are
340 encrypted using that key. All clients on the channel must also know the
341 key in order to decrypt the messages. However, it is possible to have
342 several private keys per one channel. In this case only some of the
343 clients on the channel may know the one key and only some the other key.
345 if `cipher' and/or `hmac' is NULL then default values will be used
346 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
348 The private key for channel is optional. If it is not set then the
349 channel messages are encrypted using the channel key generated by the
350 server. However, setting the private key (or keys) for the channel
351 significantly adds security. If more than one key is set the library
352 will automatically try all keys at the message decryption phase. Note:
353 setting many keys slows down the decryption phase as all keys has to
354 be tried in order to find the correct decryption key. However, setting
355 a few keys does not have big impact to the decryption performace.
357 NOTE: that this is entirely local setting. The key set using this function
358 is not sent to the network at any phase.
360 NOTE: If the key material was originated by the SKE protocol (using
361 silc_client_send_key_agreement) then the `key' MUST be the
362 key->send_enc_key as this is dictated by the SILC protocol. However,
363 currently it is not expected that the SKE key material would be used
364 as channel private key. However, this API allows it. */
366 int silc_client_add_channel_private_key(SilcClient client,
367 SilcClientConnection conn,
368 SilcChannelEntry channel,
372 unsigned int key_len)
374 SilcChannelPrivateKey entry;
375 unsigned char hash[32];
377 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
381 cipher = "aes-256-cbc";
383 hmac = "hmac-sha1-96";
385 if (!silc_cipher_is_supported(cipher))
388 if (!silc_hmac_is_supported(hmac))
391 /* Remove the current key, if it exists. */
392 if (channel->channel_key) {
393 silc_cipher_free(channel->channel_key);
394 memset(channel->key, 0, channel->key_len / 8);
395 silc_free(channel->key);
396 channel->channel_key = NULL;
398 channel->key_len = 0;
401 silc_hmac_free(channel->hmac);
403 if (!channel->private_keys)
404 channel->private_keys = silc_dlist_init();
407 entry = silc_calloc(1, sizeof(*entry));
408 entry->key = silc_calloc(key_len, sizeof(*entry->key));
409 memcpy(entry->key, key, key_len);
410 entry->key_len = key_len;
412 /* Allocate the cipher and set the key*/
413 silc_cipher_alloc(cipher, &entry->cipher);
414 silc_cipher_set_key(entry->cipher, key, key_len * 8);
416 /* Generate HMAC key from the channel key data and set it */
417 silc_hmac_alloc(hmac, NULL, &entry->hmac);
418 silc_hash_make(entry->hmac->hash, key, key_len, hash);
419 silc_hmac_set_key(entry->hmac, hash, silc_hash_len(entry->hmac->hash));
420 memset(hash, 0, sizeof(hash));
422 /* Add to the private keys list */
423 silc_dlist_add(channel->private_keys, entry);
425 if (!channel->curr_key)
426 channel->curr_key = entry;
431 /* Removes all private keys from the `channel'. The old channel key is used
432 after calling this to protect the channel messages. Returns FALSE on
433 on error, TRUE otherwise. */
435 int silc_client_del_channel_private_keys(SilcClient client,
436 SilcClientConnection conn,
437 SilcChannelEntry channel)
439 SilcChannelPrivateKey entry;
441 if (!channel->private_keys)
444 silc_dlist_start(channel->private_keys);
445 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
446 silc_dlist_del(channel->private_keys, entry);
447 memset(entry->key, 0, entry->key_len);
448 silc_free(entry->key);
449 silc_cipher_free(entry->cipher);
450 silc_hmac_free(entry->hmac);
454 channel->curr_key = NULL;
456 silc_dlist_uninit(channel->private_keys);
457 channel->private_keys = NULL;
462 /* Removes and frees private key `key' from the channel `channel'. The `key'
463 is retrieved by calling the function silc_client_list_channel_private_keys.
464 The key is not used after this. If the key was last private key then the
465 old channel key is used hereafter to protect the channel messages. This
466 returns FALSE on error, TRUE otherwise. */
468 int silc_client_del_channel_private_key(SilcClient client,
469 SilcClientConnection conn,
470 SilcChannelEntry channel,
471 SilcChannelPrivateKey key)
473 SilcChannelPrivateKey entry;
475 if (!channel->private_keys)
478 silc_dlist_start(channel->private_keys);
479 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
481 if (channel->curr_key == entry)
482 channel->curr_key = NULL;
484 silc_dlist_del(channel->private_keys, entry);
485 memset(entry->key, 0, entry->key_len);
486 silc_free(entry->key);
487 silc_cipher_free(entry->cipher);
488 silc_hmac_free(entry->hmac);
491 if (silc_dlist_count(channel->private_keys) == 0) {
492 silc_dlist_uninit(channel->private_keys);
493 channel->private_keys = NULL;
503 /* Returns array (pointers) of private keys associated to the `channel'.
504 The caller must free the array by calling the function
505 silc_client_free_channel_private_keys. The pointers in the array may be
506 used to delete the specific key by giving the pointer as argument to the
507 function silc_client_del_channel_private_key. */
509 SilcChannelPrivateKey *
510 silc_client_list_channel_private_keys(SilcClient client,
511 SilcClientConnection conn,
512 SilcChannelEntry channel,
513 unsigned int *key_count)
515 SilcChannelPrivateKey *keys = NULL, entry;
516 unsigned int count = 0;
518 if (!channel->private_keys)
521 silc_dlist_start(channel->private_keys);
522 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
523 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
534 /* Frees the SilcChannelPrivateKey array. */
536 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
537 unsigned int key_count)