updates.
authorPekka Riikonen <priikone@silcnet.org>
Thu, 12 Apr 2001 22:00:21 +0000 (22:00 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 12 Apr 2001 22:00:21 +0000 (22:00 +0000)
12 files changed:
apps/silc/client_ops.c
apps/silcd/server.c
doc/draft-riikonen-silc-spec-01.nroff
lib/silcclient/README
lib/silcclient/client.c
lib/silcclient/client.h
lib/silcclient/client_channel.c
lib/silcclient/client_prvmsg.c
lib/silcclient/protocol.c
lib/silcclient/protocol.h
lib/silccore/silcpacket.c
lib/silccore/silcpacket.h

index 3e01051c32fbafb461bbc35c01bf0ee417bb1e3e..985be666d654b7a2dd5b90225b7f254cb4d00aa8 100644 (file)
@@ -1232,17 +1232,17 @@ int silc_key_agreement(SilcClient client, SilcClientConnection conn,
 
 /* SILC client operations */
 SilcClientOperations ops = {
-  say:                  silc_say,
-  channel_message:      silc_channel_message,
-  private_message:      silc_private_message,
-  notify:               silc_notify,
-  command:              silc_command,
-  command_reply:        silc_command_reply,
-  connect:              silc_connect,
-  disconnect:           silc_disconnect,
-  get_auth_method:      silc_get_auth_method,
-  verify_public_key:    silc_verify_public_key,
-  ask_passphrase:       silc_ask_passphrase,
-  failure:              silc_failure,
-  key_agreement:        silc_key_agreement,
+  silc_say,
+  silc_channel_message,
+  silc_private_message,
+  silc_notify,
+  silc_command,
+  silc_command_reply,
+  silc_connect,
+  silc_disconnect,
+  silc_get_auth_method,
+  silc_verify_public_key,
+  silc_ask_passphrase,
+  silc_failure,
+  silc_key_agreement,
 };
index 4ebe22b66422f8fc7b73793e2f13d66bae87b169..639c3bbb732a8eb75d3b55028ba544717ac42e77 100644 (file)
@@ -1526,37 +1526,21 @@ void silc_server_packet_parse(SilcPacketParserContext *parser_context)
     break;
   case SILC_SOCKET_TYPE_CLIENT:
     /* Parse the packet with timeout (unless protocol is active) */
-
-    /* If REKEY protocol is active we must proccess the packets synchronously
-       since we must assure that incoming packets that are encrypted with
-       the old key is processed before the new keys is set to use. */
-    if (SILC_SERVER_IS_REKEY(sock))
-      silc_server_packet_parse_real(server->timeout_queue, SILC_TASK_READ,
-                                   (void *)parser_context, sock->sock);
-    else
-      silc_task_register(server->timeout_queue, sock->sock,
-                        silc_server_packet_parse_real,
-                        (void *)parser_context, 0, 
-                        (sock->protocol ? 1 : 100000),
-                        SILC_TASK_TIMEOUT,
-                        SILC_TASK_PRI_NORMAL);
+    silc_task_register(server->timeout_queue, sock->sock,
+                      silc_server_packet_parse_real,
+                      (void *)parser_context, 0, 
+                      (sock->protocol ? 1 : 100000),
+                      SILC_TASK_TIMEOUT,
+                      SILC_TASK_PRI_NORMAL);
     break;
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     /* Packets from servers are parsed as soon as possible */
-
-    /* If REKEY protocol is active we must proccess the packets synchronously
-       since we must assure that incoming packets that are encrypted with
-       the old key is processed before the new keys is set to use. */
-    if (SILC_SERVER_IS_REKEY(sock))
-      silc_server_packet_parse_real(server->timeout_queue, SILC_TASK_READ,
-                                   (void *)parser_context, sock->sock);
-    else
-      silc_task_register(server->timeout_queue, sock->sock,
-                        silc_server_packet_parse_real,
-                        (void *)parser_context, 0, 1,
-                        SILC_TASK_TIMEOUT,
-                        SILC_TASK_PRI_NORMAL);
+    silc_task_register(server->timeout_queue, sock->sock,
+                      silc_server_packet_parse_real,
+                      (void *)parser_context, 0, 1,
+                      SILC_TASK_TIMEOUT,
+                      SILC_TASK_PRI_NORMAL);
     break;
   default:
     return;
index 854a0376631ea92b626678491966f1fc81d10320..326c79cc0c1347052472068f50288d88d74401c1 100644 (file)
@@ -1791,10 +1791,15 @@ without executing SKE protocol.  In this case, the new key is created by
 hashing the old key with hash function selected earlier in the SKE
 protocol.  If the digest length of the hash function is too short for the
 key, then the key is distributed as described in section Processing the
-Key Material in [SILC3].  After both parties has regenerated the session
-key, both send SILC_PACKET_REKEY_DONE packet to each other.  These packets
-are still secured with the old key.  After these packets, the following
-packets must be protected with the new key.
+Key Material in [SILC3].
+
+After both parties has regenerated the session key, both send
+SILC_PACKET_REKEY_DONE packet to each other.  These packets are still
+secured with the old key.  After these packets, the following packets
+must be protected with the new key.  After sending the REKEY_DONE packet
+all subsequent sent packets must be encrypted with the new key.  After
+receiving the REKEY_DONE packet all subsequent packets must be
+decrypted with the new key.
 
 
 .ti 0
index 0fb6e0b40b3bcd487884f5a802f7ec8f0f91488c..499298dbf9e8ce227046c144ac0892dc7e4fc086 100644 (file)
@@ -42,18 +42,19 @@ for detailed definition of SilcClient object.
 `ops' can be defined for example as follows:
 
 SilcClientOperations ops = {
-  say:                  silc_say,
-  channel_message:      silc_channel_message,
-  private_message:      silc_private_message,
-  notify:               silc_notify,
-  command:              silc_command,
-  command_reply:        silc_command_reply,
-  connect:              silc_connect,
-  disconnect:           silc_disconnect,
-  get_auth_method:      silc_get_auth_method,
-  verify_public_key:    silc_verify_public_key,
-  ask_passphrase:       silc_ask_passphrase,
-  failure:              silc_failure,
+  silc_say,
+  silc_channel_message,
+  silc_private_message,
+  silc_notify,
+  silc_command,
+  silc_command_reply,
+  silc_connect,
+  silc_disconnect,
+  silc_get_auth_method,
+  silc_verify_public_key,
+  silc_ask_passphrase,
+  silc_failure,
+  silc_key_agreement,
 };
 
 
index 04790cdbdb930dc0bfc6dcf97ecd787820220a6d..50445d004a888aa7a3b1a638089abd2ebea723c3 100644 (file)
@@ -778,6 +778,7 @@ void silc_client_packet_parse(SilcPacketParserContext *parser_context)
 
   /* Parse the packet */
 
+#if 0
   /* If REKEY protocol is active we must proccess the packets synchronously
      since we must assure that incoming packets that are encrypted with
      the old key is processed before the new keys is set to use. */
@@ -786,6 +787,7 @@ void silc_client_packet_parse(SilcPacketParserContext *parser_context)
                                  (void *)parser_context, 
                                  parser_context->sock->sock);
   else
+#endif
     silc_task_register(client->timeout_queue, parser_context->sock->sock, 
                       silc_client_packet_parse_real,
                       (void *)parser_context, 0, 1, 
index d9e856f5295b53a30e8a1acd221a4981038a49b0..13ebfd0bcd5824dc270e1c1e64631649f1803619 100644 (file)
@@ -85,7 +85,8 @@ struct SilcClientConnectionStruct {
   /* Keys and stuff negotiated in the SKE protocol */
   SilcCipher send_key;
   SilcCipher receive_key;
-  SilcHmac hmac;
+  SilcHmac hmac_send;
+  SilcHmac hmac_receive;
   SilcHash hash;
 
   /* Client ID and Channel ID cache. Messages transmitted in SILC network
index 29880be4be91952f6a23539a97142ab611f5d0d5..62396c5f0dda0a4e98acb598ddb8526ebbf2049d 100644 (file)
@@ -100,7 +100,7 @@ void silc_client_send_channel_message(SilcClient client,
 
   /* Get data used in packet header encryption, keys and stuff. */
   cipher = conn->send_key;
-  hmac = conn->hmac;
+  hmac = conn->hmac_send;
   id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
 
   /* Set the packet context pointers. The destination ID is always
index 06f0555aaf6d3e8f8076ba0cd4b07adce4540bc0..455505163c62b6deb05ed0de31e642602cc191ca 100644 (file)
@@ -69,7 +69,7 @@ void silc_client_send_private_message(SilcClient client,
 
   /* Get data used in the encryption */
   cipher = client_entry->send_key;
-  hmac = conn->hmac;
+  hmac = conn->hmac_send;
 
   /* Set the packet context pointers. */
   packetdata.flags = SILC_PACKET_FLAG_PRIVMSG_KEY;
index a6ced2c02a68f955bf5f2aadaac3d331259c3404..cedf57679c39f794dc8f356ab24386e3032097d0 100644 (file)
@@ -128,8 +128,9 @@ void silc_client_protocol_ke_set_keys(SilcSKE ske,
   conn->rekey->ske_group = silc_ske_group_get_number(group);
 
   /* Save HMAC key to be used in the communication. */
-  silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac);
-  silc_hmac_set_key(conn->hmac, keymat->hmac_key, keymat->hmac_key_len);
+  silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac_send);
+  silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, keymat->hmac_key_len);
+  conn->hmac_receive = conn->hmac_send;
 
   /* Save the HASH function */
   silc_hash_alloc(hash->hash->name, &conn->hash);
@@ -635,51 +636,70 @@ static void
 silc_client_protocol_rekey_validate(SilcClient client,
                                    SilcClientRekeyInternalContext *ctx,
                                    SilcSocketConnection sock,
-                                   SilcSKEKeyMaterial *keymat)
+                                   SilcSKEKeyMaterial *keymat,
+                                   bool send)
 {
   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
 
   if (ctx->responder == TRUE) {
-    silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, 
-                       keymat->enc_key_len);
-    silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
-    silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, 
-                       keymat->enc_key_len);
-    silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
+    if (send) {
+      silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, 
+                         keymat->enc_key_len);
+      silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
+    } else {
+      silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, 
+                         keymat->enc_key_len);
+      silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
+    }
   } else {
-    silc_cipher_set_key(conn->send_key, keymat->send_enc_key, 
-                       keymat->enc_key_len);
-    silc_cipher_set_iv(conn->send_key, keymat->send_iv);
-    silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, 
-                       keymat->enc_key_len);
-    silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
+    if (send) {
+      silc_cipher_set_key(conn->send_key, keymat->send_enc_key, 
+                         keymat->enc_key_len);
+      silc_cipher_set_iv(conn->send_key, keymat->send_iv);
+    } else {
+      silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, 
+                         keymat->enc_key_len);
+      silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
+    }
   }
 
-  silc_hmac_set_key(conn->hmac, keymat->hmac_key, keymat->hmac_key_len);
+  if (send) {
+    silc_hmac_alloc(conn->hmac_receive->hmac->name, NULL, &conn->hmac_send);
+    silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, 
+                     keymat->hmac_key_len);
+  } else {
+    silc_hmac_free(conn->hmac_receive);
+    conn->hmac_receive = conn->hmac_send;
+  }
 
   /* Save the current sending encryption key */
-  memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
-  silc_free(conn->rekey->send_enc_key);
-  conn->rekey->send_enc_key = 
-    silc_calloc(keymat->enc_key_len / 8,
-               sizeof(*conn->rekey->send_enc_key));
-  memcpy(conn->rekey->send_enc_key, keymat->send_enc_key, 
-        keymat->enc_key_len / 8);
-  conn->rekey->enc_key_len = keymat->enc_key_len / 8;
+  if (!send) {
+    memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
+    silc_free(conn->rekey->send_enc_key);
+    conn->rekey->send_enc_key = 
+      silc_calloc(keymat->enc_key_len / 8,
+                 sizeof(*conn->rekey->send_enc_key));
+    memcpy(conn->rekey->send_enc_key, keymat->send_enc_key, 
+          keymat->enc_key_len / 8);
+    conn->rekey->enc_key_len = keymat->enc_key_len / 8;
+  }
 }
 
 /* This function actually re-generates (when not using PFS) the keys and
    takes them into use. */
 
-void silc_client_protocol_rekey_generate(SilcClient client,
-                                        SilcClientRekeyInternalContext *ctx)
+static void 
+silc_client_protocol_rekey_generate(SilcClient client,
+                                   SilcClientRekeyInternalContext *ctx,
+                                   bool send)
 {
   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
   SilcSKEKeyMaterial *keymat;
   uint32 key_len = silc_cipher_get_key_len(conn->send_key);
   uint32 hash_len = conn->hash->hash->hash_len;
 
-  SILC_LOG_DEBUG(("Generating new session keys (no PFS)"));
+  SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
+                 send ? "sending" : "receiving"));
 
   /* Generate the new key */
   keymat = silc_calloc(1, sizeof(*keymat));
@@ -689,7 +709,7 @@ void silc_client_protocol_rekey_generate(SilcClient client,
                                     conn->hash, keymat);
 
   /* Set the keys into use */
-  silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat);
+  silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
 
   silc_ske_free_key_material(keymat);
 }
@@ -697,9 +717,10 @@ void silc_client_protocol_rekey_generate(SilcClient client,
 /* This function actually re-generates (with PFS) the keys and
    takes them into use. */
 
-void 
+static void 
 silc_client_protocol_rekey_generate_pfs(SilcClient client,
-                                       SilcClientRekeyInternalContext *ctx)
+                                       SilcClientRekeyInternalContext *ctx,
+                                       bool send)
 {
   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
   SilcSKEKeyMaterial *keymat;
@@ -708,7 +729,8 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client,
   unsigned char *tmpbuf;
   uint32 klen;
 
-  SILC_LOG_DEBUG(("Generating new session keys (with PFS)"));
+  SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
+                 send ? "sending" : "receiving"));
 
   /* Encode KEY to binary data */
   tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
@@ -719,7 +741,7 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client,
                                     conn->hash, keymat);
 
   /* Set the keys into use */
-  silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat);
+  silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
 
   memset(tmpbuf, 0, klen);
   silc_free(tmpbuf);
@@ -741,8 +763,8 @@ silc_client_protocol_rekey_send_packet(SilcSKE ske,
   SilcClient client = (SilcClient)ctx->client;
 
   /* Send the packet immediately */
-  silc_client_packet_send_flush(client, ctx->sock, type, NULL, 0, NULL, NULL,
-                               packet->data, packet->len);
+  silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
+                         packet->data, packet->len, FALSE);
 }
 
 /* Performs re-key as defined in the SILC protocol specification. */
@@ -815,9 +837,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
           */
 
          /* Send the REKEY_DONE to indicate we will take new keys into use */
-         silc_client_packet_send_flush(client, ctx->sock, 
-                                       SILC_PACKET_REKEY_DONE, 
-                                       NULL, 0, NULL, NULL, NULL, 0);
+         silc_client_packet_send(client, ctx->sock, 
+                                 SILC_PACKET_REKEY_DONE, 
+                                 NULL, 0, NULL, NULL, NULL, 0, FALSE);
+
+         /* After we send REKEY_DONE we must set the sending encryption
+            key to the new key since all packets after this packet must
+            encrypted with the new key. */
+         silc_client_protocol_rekey_generate(client, ctx, TRUE);
 
          /* The protocol ends in next stage. */
          protocol->state = SILC_PROTOCOL_STATE_END;
@@ -829,8 +856,8 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
         */
 
        /* Start the re-key by sending the REKEY packet */
-       silc_client_packet_send_flush(client, ctx->sock, SILC_PACKET_REKEY, 
-                                     NULL, 0, NULL, NULL, NULL, 0);
+       silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY, 
+                               NULL, 0, NULL, NULL, NULL, 0, FALSE);
 
        if (ctx->pfs == TRUE) {
          /* 
@@ -867,9 +894,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
 
          /* Send the REKEY_DONE to indicate we will take new keys into use 
             now. */ 
-         silc_client_packet_send_flush(client, ctx->sock, 
-                                       SILC_PACKET_REKEY_DONE, 
-                                       NULL, 0, NULL, NULL, NULL, 0);
+         silc_client_packet_send(client, ctx->sock, 
+                                 SILC_PACKET_REKEY_DONE, 
+                                 NULL, 0, NULL, NULL, NULL, 0, FALSE);
+
+         /* After we send REKEY_DONE we must set the sending encryption
+            key to the new key since all packets after this packet must
+            encrypted with the new key. */
+         silc_client_protocol_rekey_generate(client, ctx, TRUE);
 
          /* The protocol ends in next stage. */
          protocol->state = SILC_PROTOCOL_STATE_END;
@@ -932,9 +964,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
 
     /* Send the REKEY_DONE to indicate we will take new keys into use 
        now. */ 
-    silc_client_packet_send_flush(client, ctx->sock, SILC_PACKET_REKEY_DONE, 
-                                 NULL, 0, NULL, NULL, NULL, 0);
+    silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE, 
+                           NULL, 0, NULL, NULL, NULL, 0, FALSE);
     
+    /* After we send REKEY_DONE we must set the sending encryption
+       key to the new key since all packets after this packet must
+       encrypted with the new key. */
+    silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
+
     /* The protocol ends in next stage. */
     protocol->state = SILC_PROTOCOL_STATE_END;
     break;
@@ -950,6 +987,10 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
       protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
     }
 
+    /* We received the REKEY_DONE packet and all packets after this is
+       encrypted with the new key so set the decryption key to the new key */
+    silc_client_protocol_rekey_generate(client, ctx, FALSE);
+
     /* Protocol has ended, call the final callback */
     if (protocol->final_callback)
       protocol->execute_final(client->timeout_queue, 0, protocol, fd);
index 71e25069b9d00e8791e4d83e47441c7b590d56f8..e55f4c66846ab75009b545fb4dc55301e37ac832 100644 (file)
@@ -104,10 +104,5 @@ void silc_client_protocol_ke_set_keys(SilcSKE ske,
                                      SilcHash hash,
                                      SilcHmac hmac,
                                      SilcSKEDiffieHellmanGroup group);
-void silc_client_protocol_rekey_generate(SilcClient client,
-                                        SilcClientRekeyInternalContext *ctx);
-void 
-silc_client_protocol_rekey_generate_pfs(SilcClient client,
-                                       SilcClientRekeyInternalContext *ctx);
 
 #endif
index 1708226e1bfffec89beb06e29edb1d236bd1b259..0911ca06a52d165505aea26c51f3b2c09ff62b53 100644 (file)
@@ -403,8 +403,6 @@ void silc_packet_receive_process(SilcSocketConnection sock,
     parse_ctx->packet = silc_packet_context_alloc();
     parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
     parse_ctx->sock = sock;
-    parse_ctx->cipher = cipher;
-    parse_ctx->hmac = hmac;
     parse_ctx->context = context;
 
     silc_buffer_pull_tail(parse_ctx->packet->buffer, 
index 30a9cc51d65300ea6fd8d7a98bab213bee3f0cd0..792482276e7efd13b0447949f9bc0477b2033822 100644 (file)
@@ -158,14 +158,6 @@ typedef struct {
 
        The associated connection.
 
-   SilcCipher cipher
-
-       The cipher to be used in the decryption.
-
-   SilcHmac hmac
-
-       The HMAC to be used in the decryption.
-
    void *context
 
        User context that is sent to the silc_packet_receive_process
@@ -177,8 +169,6 @@ typedef struct {
 typedef struct {
   SilcPacketContext *packet;
   SilcSocketConnection sock;
-  SilcCipher cipher;
-  SilcHmac hmac;
   void *context;
 } SilcPacketParserContext;