From 03df183a5ada5bad0eed82b78d93ca6f4fd51213 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 16 Jan 2007 13:51:36 +0000 Subject: [PATCH] Fixed channel key setting. --- lib/silcclient/client.h | 3 ++- lib/silcclient/client_channel.c | 30 ++++++++++++++++++++++-------- lib/silcclient/client_entry.c | 6 ++++-- lib/silcclient/client_register.c | 4 ++-- lib/silcclient/command_reply.c | 4 ++-- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index 147dcbd1..1a6da14e 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -74,7 +74,8 @@ typedef struct SilcChannelEntryInternalStruct { SilcChannelPrivateKey curr_key; /* Current private key */ /* Channel keys */ - SilcCipher channel_key; /* The channel key */ + SilcCipher send_key; /* The channel key */ + SilcCipher receive_key; /* The channel key */ SilcHmac hmac; /* Current HMAC */ unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; /* Current IV */ diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index e7753b94..4492153c 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -94,12 +94,12 @@ SilcBool silc_client_send_channel_message(SilcClient client, channel->internal.curr_key = key; } else { /* Use normal channel key generated by the server */ - cipher = channel->internal.channel_key; + cipher = channel->internal.send_key; hmac = channel->internal.hmac; } } else { /* Use normal channel key generated by the server */ - cipher = channel->internal.channel_key; + cipher = channel->internal.send_key; hmac = channel->internal.hmac; } @@ -163,6 +163,9 @@ SILC_FSM_STATE(silc_client_channel_message) SILC_LOG_DEBUG(("Received channel message")); + SILC_LOG_HEXDUMP(("Channel message"), silc_buffer_data(buffer), + silc_buffer_len(buffer)); + if (silc_unlikely(packet->dst_id_type != SILC_ID_CHANNEL)) { /** Invalid packet */ silc_fsm_next(fsm, silc_client_channel_message_error); @@ -221,7 +224,7 @@ SILC_FSM_STATE(silc_client_channel_message) /* Parse the channel message payload. This also decrypts the payload */ payload = silc_message_payload_parse(silc_buffer_data(buffer), silc_buffer_len(buffer), FALSE, - FALSE, channel->internal.channel_key, + FALSE, channel->internal.receive_key, channel->internal.hmac, NULL, FALSE, NULL); @@ -262,7 +265,7 @@ SILC_FSM_STATE(silc_client_channel_message) payload = silc_message_payload_parse(silc_buffer_data(buffer), silc_buffer_len(buffer), FALSE, FALSE, - channel->internal.channel_key, + channel->internal.receive_key, channel->internal.hmac, NULL, FALSE, NULL); @@ -390,7 +393,7 @@ SilcBool silc_client_save_channel_key(SilcClient client, channel->internal.old_hmacs = silc_dlist_init(); if (channel->internal.old_channel_keys && channel->internal.old_hmacs) { silc_dlist_add(channel->internal.old_channel_keys, - channel->internal.channel_key); + channel->internal.receive_key); silc_dlist_add(channel->internal.old_hmacs, channel->internal.hmac); silc_schedule_task_add_timeout(client->schedule, silc_client_save_channel_key_rekey, @@ -399,7 +402,17 @@ SilcBool silc_client_save_channel_key(SilcClient client, /* Get channel cipher */ cipher = silc_channel_key_get_cipher(payload, NULL); - if (!silc_cipher_alloc(cipher, &channel->internal.channel_key)) { + if (!silc_cipher_alloc(cipher, &channel->internal.send_key)) { + client->internal->ops->say( + conn->client, conn, + SILC_CLIENT_MESSAGE_AUDIT, + "Cannot talk to channel: unsupported cipher %s", + cipher); + silc_client_unref_channel(client, conn, channel); + silc_channel_key_payload_free(payload); + return FALSE; + } + if (!silc_cipher_alloc(cipher, &channel->internal.receive_key)) { client->internal->ops->say( conn->client, conn, SILC_CLIENT_MESSAGE_AUDIT, @@ -410,9 +423,10 @@ SilcBool silc_client_save_channel_key(SilcClient client, return FALSE; } - /* Set the cipher key */ + /* Set the cipher key. Both sending and receiving keys are same */ key = silc_channel_key_get_key(payload, &tmp_len); - silc_cipher_set_key(channel->internal.channel_key, key, tmp_len * 8, TRUE); + silc_cipher_set_key(channel->internal.send_key, key, tmp_len * 8, TRUE); + silc_cipher_set_key(channel->internal.receive_key, key, tmp_len * 8, FALSE); /* Get channel HMAC */ hmac = (channel->internal.hmac ? diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index a58298fc..0f04e084 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -1493,8 +1493,10 @@ SilcBool silc_client_del_channel(SilcClient client, SilcClientConnection conn, silc_free(channel->topic); if (channel->founder_key) silc_pkcs_public_key_free(channel->founder_key); - if (channel->internal.channel_key) - silc_cipher_free(channel->internal.channel_key); + if (channel->internal.send_key) + silc_cipher_free(channel->internal.send_key); + if (channel->internal.receive_key) + silc_cipher_free(channel->internal.receive_key); if (channel->internal.hmac) silc_hmac_free(channel->internal.hmac); if (channel->internal.old_channel_keys) { diff --git a/lib/silcclient/client_register.c b/lib/silcclient/client_register.c index f029c480..29012102 100644 --- a/lib/silcclient/client_register.c +++ b/lib/silcclient/client_register.c @@ -571,8 +571,8 @@ SILC_FSM_STATE(silc_client_st_resume_completed) const char *cipher, *hmac; channel = entry->context; - cipher = (channel->internal.channel_key ? - silc_cipher_get_name(channel->internal.channel_key) : NULL); + cipher = (channel->internal.send_key ? + silc_cipher_get_name(channel->internal.send_key) : NULL); hmac = (channel->internal.hmac ? silc_hmac_get_name(channel->internal.hmac) : NULL); silc_hash_table_list(channel->user_list, &htl); diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index c1c7b190..39e0f928 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -1273,8 +1273,8 @@ SILC_FSM_STATE(silc_client_command_reply_join) /* Set current channel */ conn->current_channel = channel; - cipher = (channel->internal.channel_key ? - silc_cipher_get_name(channel->internal.channel_key) : NULL); + cipher = (channel->internal.send_key ? + silc_cipher_get_name(channel->internal.send_key) : NULL); silc_hash_table_list(channel->user_list, &htl); /* Notify application */ -- 2.24.0