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, FALSE);
150 silc_buffer_free(payload);
151 silc_free(id_string);
154 /* Process received message to a channel (or from a channel, really). This
155 decrypts the channel message with channel specific key and parses the
156 channel payload. Finally it displays the message on the screen. */
158 void silc_client_channel_message(SilcClient client,
159 SilcSocketConnection sock,
160 SilcPacketContext *packet)
162 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
163 SilcBuffer buffer = packet->buffer;
164 SilcChannelMessagePayload payload = NULL;
165 SilcChannelID *id = NULL;
166 SilcChannelEntry channel;
168 SilcIDCacheEntry id_cache = NULL;
169 SilcClientID *client_id = NULL;
171 unsigned char *message;
173 SILC_LOG_DEBUG(("Start"));
176 if (packet->dst_id_type != SILC_ID_CHANNEL)
179 client_id = silc_id_str2id(packet->src_id, packet->src_id_len,
183 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
187 /* Find the channel entry from channels on this connection */
188 if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id, &id_cache))
191 channel = (SilcChannelEntry)id_cache->context;
193 /* If there is no channel private key then just decrypt the message
194 with the channel key. If private keys are set then just go through
195 all private keys and check what decrypts correctly. */
196 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
197 /* Parse the channel message payload. This also decrypts the payload */
198 payload = silc_channel_message_payload_parse(buffer, channel->channel_key,
202 } else if (channel->private_keys) {
203 SilcChannelPrivateKey entry;
205 silc_dlist_start(channel->private_keys);
206 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
207 /* Parse the channel message payload. This also decrypts the payload */
208 payload = silc_channel_message_payload_parse(buffer, entry->cipher,
213 if (entry == SILC_LIST_END)
219 message = silc_channel_message_get_data(payload, NULL);
221 /* Find client entry */
222 silc_list_start(channel->clients);
223 while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
224 if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id)) {
230 /* Pass the message to application */
231 client->ops->channel_message(client, conn, found ? chu->client : NULL,
233 silc_channel_message_get_flags(payload),
240 silc_free(client_id);
242 silc_channel_message_payload_free(payload);
245 /* Saves channel key from encoded `key_payload'. This is used when we
246 receive Channel Key Payload and when we are processing JOIN command
249 void silc_client_save_channel_key(SilcClientConnection conn,
250 SilcBuffer key_payload,
251 SilcChannelEntry channel)
253 unsigned char *id_string, *key, *cipher, hash[32];
256 SilcIDCacheEntry id_cache = NULL;
257 SilcChannelKeyPayload payload;
259 payload = silc_channel_key_payload_parse(key_payload);
263 id_string = silc_channel_key_get_id(payload, &tmp_len);
265 silc_channel_key_payload_free(payload);
269 id = silc_id_str2id(id_string, tmp_len, SILC_ID_CHANNEL);
271 silc_channel_key_payload_free(payload);
277 if (!silc_idcache_find_by_id_one(conn->channel_cache,
278 (void *)id, &id_cache))
281 /* Get channel entry */
282 channel = (SilcChannelEntry)id_cache->context;
286 key = silc_channel_key_get_key(payload, &tmp_len);
287 cipher = silc_channel_key_get_cipher(payload, NULL);
288 channel->key_len = tmp_len * 8;
289 channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
290 memcpy(channel->key, key, tmp_len);
292 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
293 conn->client->ops->say(conn->client, conn,
294 "Cannot talk to channel: unsupported cipher %s", cipher);
298 /* Set the cipher key */
299 silc_cipher_set_key(channel->channel_key, key, channel->key_len);
301 /* Generate HMAC key from the channel key data and set it */
303 silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
304 silc_hash_make(channel->hmac->hash, key, tmp_len, hash);
305 silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
306 memset(hash, 0, sizeof(hash));
310 silc_channel_key_payload_free(payload);
313 /* Processes received key for channel. The received key will be used
314 to protect the traffic on the channel for now on. Client must receive
315 the key to the channel before talking on the channel is possible.
316 This is the key that server has generated, this is not the channel
317 private key, it is entirely local setting. */
319 void silc_client_receive_channel_key(SilcClient client,
320 SilcSocketConnection sock,
323 SILC_LOG_DEBUG(("Received key for channel"));
326 silc_client_save_channel_key(sock->user_data, packet, NULL);
329 /* Adds private key for channel. This may be set only if the channel's mode
330 mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
331 mode is not set. When channel has private key then the messages are
332 encrypted using that key. All clients on the channel must also know the
333 key in order to decrypt the messages. However, it is possible to have
334 several private keys per one channel. In this case only some of the
335 clients on the channel may know the one key and only some the other key.
337 If `cipher' and/or `hmac' is NULL then default values will be used
338 (aes-256-cbc for cipher and hmac-sha1-96 for hmac).
340 The private key for channel is optional. If it is not set then the
341 channel messages are encrypted using the channel key generated by the
342 server. However, setting the private key (or keys) for the channel
343 significantly adds security. If more than one key is set the library
344 will automatically try all keys at the message decryption phase. Note:
345 setting many keys slows down the decryption phase as all keys has to
346 be tried in order to find the correct decryption key. However, setting
347 a few keys does not have big impact to the decryption performace.
349 NOTE: that this is entirely local setting. The key set using this function
350 is not sent to the network at any phase.
352 NOTE: If the key material was originated by the SKE protocol (using
353 silc_client_send_key_agreement) then the `key' MUST be the
354 key->send_enc_key as this is dictated by the SILC protocol. However,
355 currently it is not expected that the SKE key material would be used
356 as channel private key. However, this API allows it. */
358 int silc_client_add_channel_private_key(SilcClient client,
359 SilcClientConnection conn,
360 SilcChannelEntry channel,
366 SilcChannelPrivateKey entry;
367 unsigned char hash[32];
368 SilcSKEKeyMaterial *keymat;
370 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
374 cipher = "aes-256-cbc";
376 hmac = "hmac-sha1-96";
378 if (!silc_cipher_is_supported(cipher))
381 if (!silc_hmac_is_supported(hmac))
384 /* Produce the key material */
385 keymat = silc_calloc(1, sizeof(*keymat));
386 if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
387 client->md5hash, keymat)
388 != SILC_SKE_STATUS_OK)
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);
402 channel->hmac = NULL;
405 if (!channel->private_keys)
406 channel->private_keys = silc_dlist_init();
409 entry = silc_calloc(1, sizeof(*entry));
410 entry->key = silc_calloc(keymat->enc_key_len / 8, sizeof(*entry->key));
411 memcpy(entry->key, keymat->send_enc_key, keymat->enc_key_len / 8);
412 entry->key_len = keymat->enc_key_len / 8;
414 /* Allocate the cipher and set the key*/
415 silc_cipher_alloc(cipher, &entry->cipher);
416 silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len);
418 /* Generate HMAC key from the channel key data and set it */
419 silc_hmac_alloc(hmac, NULL, &entry->hmac);
420 silc_hash_make(entry->hmac->hash, entry->key, entry->key_len, hash);
421 silc_hmac_set_key(entry->hmac, hash, silc_hash_len(entry->hmac->hash));
422 memset(hash, 0, sizeof(hash));
424 /* Add to the private keys list */
425 silc_dlist_add(channel->private_keys, entry);
427 if (!channel->curr_key)
428 channel->curr_key = entry;
430 /* Free the key material */
431 silc_ske_free_key_material(keymat);
436 /* Removes all private keys from the `channel'. The old channel key is used
437 after calling this to protect the channel messages. Returns FALSE on
438 on error, TRUE otherwise. */
440 int silc_client_del_channel_private_keys(SilcClient client,
441 SilcClientConnection conn,
442 SilcChannelEntry channel)
444 SilcChannelPrivateKey entry;
446 if (!channel->private_keys)
449 silc_dlist_start(channel->private_keys);
450 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
451 silc_dlist_del(channel->private_keys, entry);
452 memset(entry->key, 0, entry->key_len);
453 silc_free(entry->key);
454 silc_cipher_free(entry->cipher);
455 silc_hmac_free(entry->hmac);
459 channel->curr_key = NULL;
461 silc_dlist_uninit(channel->private_keys);
462 channel->private_keys = NULL;
467 /* Removes and frees private key `key' from the channel `channel'. The `key'
468 is retrieved by calling the function silc_client_list_channel_private_keys.
469 The key is not used after this. If the key was last private key then the
470 old channel key is used hereafter to protect the channel messages. This
471 returns FALSE on error, TRUE otherwise. */
473 int silc_client_del_channel_private_key(SilcClient client,
474 SilcClientConnection conn,
475 SilcChannelEntry channel,
476 SilcChannelPrivateKey key)
478 SilcChannelPrivateKey entry;
480 if (!channel->private_keys)
483 silc_dlist_start(channel->private_keys);
484 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
486 if (channel->curr_key == entry)
487 channel->curr_key = NULL;
489 silc_dlist_del(channel->private_keys, entry);
490 memset(entry->key, 0, entry->key_len);
491 silc_free(entry->key);
492 silc_cipher_free(entry->cipher);
493 silc_hmac_free(entry->hmac);
496 if (silc_dlist_count(channel->private_keys) == 0) {
497 silc_dlist_uninit(channel->private_keys);
498 channel->private_keys = NULL;
508 /* Returns array (pointers) of private keys associated to the `channel'.
509 The caller must free the array by calling the function
510 silc_client_free_channel_private_keys. The pointers in the array may be
511 used to delete the specific key by giving the pointer as argument to the
512 function silc_client_del_channel_private_key. */
514 SilcChannelPrivateKey *
515 silc_client_list_channel_private_keys(SilcClient client,
516 SilcClientConnection conn,
517 SilcChannelEntry channel,
520 SilcChannelPrivateKey *keys = NULL, entry;
523 if (!channel->private_keys)
526 silc_dlist_start(channel->private_keys);
527 while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
528 keys = silc_realloc(keys, sizeof(*keys) * (count + 1));
539 /* Frees the SilcChannelPrivateKey array. */
541 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,