Fixed channel key setting.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 16 Jan 2007 13:51:36 +0000 (13:51 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 16 Jan 2007 13:51:36 +0000 (13:51 +0000)
lib/silcclient/client.h
lib/silcclient/client_channel.c
lib/silcclient/client_entry.c
lib/silcclient/client_register.c
lib/silcclient/command_reply.c

index 147dcbd1caa51338603e3c93eab895e50296f44b..1a6da14ebbdd0547ccb7e7ad5364aa1665a663e9 100644 (file)
@@ -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 */
 
index e7753b9400e8c99fec30b2043739ea3bd89c9c49..4492153c0320b9d264edafb04d543c0bbbe6c09a 100644 (file)
@@ -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 ?
index a58298fc05f81ebf0610ce48f9455910eb0d097f..0f04e08401438cff0a70169910534725879f4128 100644 (file)
@@ -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) {
index f029c480079c3fcabb022d257229329e7fc90bce..2901210288d95dfa50e8f8c41706131b17e3f998 100644 (file)
@@ -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);
index c1c7b190c2436e2487320dcebc4b2cfc05b718db..39e0f92837e71ecabbb53d3f1ea81e5972e7a900 100644 (file)
@@ -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 */