updates.
authorPekka Riikonen <priikone@silcnet.org>
Wed, 4 Apr 2001 14:36:20 +0000 (14:36 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 4 Apr 2001 14:36:20 +0000 (14:36 +0000)
14 files changed:
CHANGES
apps/silc/local_command.c
apps/silcd/idlist.c
apps/silcd/idlist.h
apps/silcd/packet_receive.c
apps/silcd/packet_receive.h
apps/silcd/protocol.c
apps/silcd/protocol.h
apps/silcd/server.c
apps/silcd/server_internal.h
doc/draft-riikonen-silc-ke-auth-02.nroff
doc/draft-riikonen-silc-pp-02.nroff
doc/draft-riikonen-silc-spec-02.nroff
lib/silccore/silcpacket.h

diff --git a/CHANGES b/CHANGES
index f4fff9d6b4ada47bf1e4537795a73342d1d2813c..6a860723407f325f30c9f6f2a4bc23fc396ad409 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,28 @@
+Wed Apr  4 16:32:31 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Do not ask whether user wants to use the negotiated private key
+         for private messages, just use it.  Affected file is 
+         silc/local_command.c.
+
+       * Added `send_enc_key' and `enc_key_len' fields to the 
+         SilcIDListData structure since they are needed in the re-key
+         phase.  Affected file is silcd/idlist.[ch].
+
+       * Implemented the simple re-key protocol into the server.
+         Affected files silcd/server.c and silcd/protocol.[ch].  The
+         re-key will be performed once in an hour, by default.
+
+         Added new protocol type SILC_PROTOCOL_SERVER_REKEY.
+         Added silc_server_rekey, silc_server_rekey_callback and
+         silc_server_rekey_final.
+
+       * Removed Tunneled flag from the protocol.  Updated the code
+         and the specifications.
+
+       * Adde `pfs' field to the SilcIDListData to indicate whether
+         the PFS is to be performed in the re-key.  Affected file is
+         silcd/idlist.h.
+
 Tue Apr  3 21:52:42 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Defined uint8, int8, uint16, int16, uint32, int32, uint64 and
index db1f9c6dc2a98dafb6d4c6e271d3fa359e80686d..fae582a759befd7769a214a625d30f686f54d9d9 100644 (file)
@@ -302,13 +302,6 @@ static void keyagr_completion(SilcClient client,
             client_entry->nickname);;
 
     if (i->type == 1) {
-      if (!silc_client_ask_yes_no(client, 
-         "Would you like to use the key with private messages (y/n)? ")) {
-       silc_say(client, conn, "You can set the key material into use later by giving /KEY msg set command");
-       curr_key = key;
-       break;
-      }
-      
       /* Set the private key for this client */
       silc_client_del_private_message_key(client, conn, client_entry);
       silc_client_add_private_message_key_ske(client, conn, client_entry,
index 7e4aa75257292d51b3a7afed46cd03d416166621..ba9eaf66ea8034161857a9d930ee20361c06ba35 100644 (file)
@@ -36,10 +36,9 @@ void silc_idlist_add_data(void *entry, SilcIDListData idata)
   SilcIDListData data = (SilcIDListData)entry;
   data->send_key = idata->send_key;
   data->receive_key = idata->receive_key;
+  data->rekey = idata->rekey;
   data->hash = idata->hash;
   data->hmac = idata->hmac;
-  data->hmac_key = idata->hmac_key;
-  data->hmac_key_len = idata->hmac_key_len;
   data->public_key = idata->public_key;
   data->last_receive = idata->last_receive;
   data->last_sent = idata->last_sent;
@@ -55,12 +54,15 @@ void silc_idlist_del_data(void *entry)
     silc_cipher_free(idata->send_key);
   if (idata->receive_key)
     silc_cipher_free(idata->receive_key);
+  if (idata->rekey) {
+    if (idata->rekey->send_enc_key) {
+      memset(idata->rekey->send_enc_key, 0, idata->rekey->enc_key_len);
+      silc_free(idata->rekey->send_enc_key);
+    }
+    silc_free(idata->rekey);
+  }
   if (idata->hmac)
     silc_hmac_free(idata->hmac);
-  if (idata->hmac_key) {
-    memset(idata->hmac_key, 0, idata->hmac_key_len);
-    silc_free(idata->hmac_key);
-  }
   if (idata->public_key)
     silc_pkcs_public_key_free(idata->public_key);
 }
@@ -250,6 +252,8 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
 
 int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry)
 {
+  SILC_LOG_DEBUG(("Start"));
+
   if (entry) {
     /* Remove from cache */
     if (entry->id)
@@ -321,6 +325,8 @@ silc_idlist_add_client(SilcIDList id_list, unsigned char *nickname,
 
 int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
 {
+  SILC_LOG_DEBUG(("Start"));
+
   if (entry) {
     /* Remove from cache */
     if (entry->id)
@@ -609,6 +615,8 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
 
 int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
 {
+  SILC_LOG_DEBUG(("Start"));
+
   if (entry) {
     SilcChannelClientEntry chl;
 
index eff107b6aae2d84327a9792653dd3ffee5713a90..803392f2e923ffd6eb714850f43603701a514abe 100644 (file)
@@ -40,6 +40,17 @@ typedef struct {
   uint32 key_len;
 } *SilcServerChannelRekey;
 
+/* Generic rekey context for connections */
+typedef struct {
+  /* Current sending encryption key, provided for re-key. The `pfs'
+     is TRUE if the Perfect Forward Secrecy is performed in re-key. */
+  unsigned char *send_enc_key;
+  uint32 enc_key_len;
+  bool pfs;
+  uint32 timeout;
+  void *context;
+} *SilcServerRekey;
+
 /*
    Generic ID list data structure.
 
@@ -58,20 +69,21 @@ typedef struct {
   SilcCipher send_key;
   SilcCipher receive_key;
 
+  /* Re-key context */
+  SilcServerRekey rekey;
+
   /* Hash selected in the SKE protocol, NULL if not needed at all */
   SilcHash hash;
 
-  /* HMAC and raw key data */
+  /* HMAC */
   SilcHmac hmac;
-  unsigned char *hmac_key;
-  uint32 hmac_key_len;
 
-  /* public key */
+  /* Public key */
   SilcPublicKey public_key;
 
   long last_receive;         /* Time last received data */
   long last_sent;           /* Time last sent data */
-  unsigned char registered;  /* Boolean whether connection is registered */
+  bool registered;           /* Boolean whether connection is registered */
 } *SilcIDListData, SilcIDListDataStruct;
 
 /* 
@@ -264,7 +276,7 @@ typedef struct SilcChannelClientEntryStruct {
        not allow any command to be exeucted more than once in about
        2 seconds. This is result of normal time().
 
-   char fast_command
+   uint8 fast_command
 
        Counter to check command bursts.  By default, up to 5 commands
        are allowed before limiting the execution.  See command flags
@@ -299,7 +311,7 @@ struct SilcClientEntryStruct {
   int mode;
 
   long last_command;
-  char fast_command;
+  uint8 fast_command;
 
   /* Pointer to the router */
   SilcServerEntry router;
@@ -343,7 +355,7 @@ struct SilcClientEntryStruct {
        ID of the channel. This includes all the information SILC will ever
        need.
 
-   int global_users
+   bool global_users
  
        Boolean value to tell whether there are users outside this server
        on this channel. This is set to TRUE if router sends message to
@@ -410,7 +422,7 @@ struct SilcChannelEntryStruct {
   char *channel_name;
   uint32 mode;
   SilcChannelID *id;
-  int global_users;
+  bool global_users;
   char *topic;
   char *cipher;
   char *hmac_name;
index 2f61ac896094c8fc9dd71cedaaed243b075321ab..2d254cfd65a878bf23379f357a1ca561890e719c 100644 (file)
@@ -2026,3 +2026,32 @@ void silc_server_connection_auth_request(SilcServer server,
                                           conn_type,
                                           auth_meth);
 }
+
+/* Received REKEY packet. The sender of the packet wants to regenerate
+   its session keys. This starts the REKEY protocol. */
+
+void silc_server_rekey(SilcServer server,
+                      SilcSocketConnection sock,
+                      SilcPacketContext *packet)
+{
+  SilcProtocol protocol;
+  SilcServerRekeyInternalContext *proto_ctx;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  /* Allocate internal protocol context. This is sent as context
+     to the protocol. */
+  proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
+  proto_ctx->server = (void *)server;
+  proto_ctx->sock = sock;
+  proto_ctx->responder = TRUE;
+      
+  /* Perform rekey protocol. Will call the final callback after the
+     protocol is over. */
+  silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
+                     &protocol, proto_ctx, silc_server_rekey_final);
+  sock->protocol = protocol;
+
+  /* Run the protocol */
+  protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);
+}
index 956c422366709c798617651b4f7f690c255fbd1e..0f14ce0453e93d91c1d8409ec4a0287e3a7bd0f1 100644 (file)
@@ -72,5 +72,8 @@ void silc_server_key_agreement(SilcServer server,
 void silc_server_connection_auth_request(SilcServer server,
                                         SilcSocketConnection sock,
                                         SilcPacketContext *packet);
+void silc_server_rekey(SilcServer server,
+                      SilcSocketConnection sock,
+                      SilcPacketContext *packet);
 
 #endif
index 5faa32489e9e934f246e6079edcd52de07041408..339f9881cc95f7bbe893cb2db714e00372c8e919 100644 (file)
@@ -61,7 +61,7 @@ int silc_server_protocol_ke_set_keys(SilcSKE ske,
                                     SilcPKCS pkcs,
                                     SilcHash hash,
                                     SilcHmac hmac,
-                                    int is_responder)
+                                    bool is_responder)
 {
   SilcUnknownEntry conn_data;
   SilcIDListData idata;
@@ -82,26 +82,33 @@ int silc_server_protocol_ke_set_keys(SilcSKE ske,
   }
   
   if (is_responder == TRUE) {
-    idata->send_key->cipher->set_key(idata->send_key->context, 
-                                    keymat->receive_enc_key, 
-                                    keymat->enc_key_len);
-    idata->send_key->set_iv(idata->send_key, keymat->receive_iv);
-    idata->receive_key->cipher->set_key(idata->receive_key->context, 
-                                       keymat->send_enc_key, 
-                                       keymat->enc_key_len);
-    idata->receive_key->set_iv(idata->receive_key, keymat->send_iv);
-    
+    silc_cipher_set_key(idata->send_key, keymat->receive_enc_key, 
+                       keymat->enc_key_len);
+    silc_cipher_set_iv(idata->send_key, keymat->receive_iv);
+    silc_cipher_set_key(idata->receive_key, keymat->send_enc_key, 
+                       keymat->enc_key_len);
+    silc_cipher_set_iv(idata->receive_key, keymat->send_iv);
   } else {
-    idata->send_key->cipher->set_key(idata->send_key->context, 
-                                    keymat->send_enc_key, 
-                                    keymat->enc_key_len);
-    idata->send_key->set_iv(idata->send_key, keymat->send_iv);
-    idata->receive_key->cipher->set_key(idata->receive_key->context, 
-                                       keymat->receive_enc_key, 
-                                       keymat->enc_key_len);
-    idata->receive_key->set_iv(idata->receive_key, keymat->receive_iv);
+    silc_cipher_set_key(idata->send_key, keymat->send_enc_key, 
+                       keymat->enc_key_len);
+    silc_cipher_set_iv(idata->send_key, keymat->send_iv);
+    silc_cipher_set_key(idata->receive_key, keymat->receive_enc_key, 
+                       keymat->enc_key_len);
+    silc_cipher_set_iv(idata->receive_key, keymat->receive_iv);
   }
 
+  /* Note that for responder the initiator's sending key is receiving key */
+  idata->rekey = silc_calloc(1, sizeof(*idata->rekey));
+  idata->rekey->send_enc_key = 
+    silc_calloc(keymat->enc_key_len / 8,
+               sizeof(*idata->rekey->send_enc_key));
+  memcpy(idata->rekey->send_enc_key, 
+        keymat->send_enc_key, keymat->enc_key_len / 8);
+  idata->rekey->enc_key_len = keymat->enc_key_len / 8;
+
+  if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
+    idata->rekey->pfs = TRUE;
+
   /* Save the remote host's public key */
   silc_pkcs_public_key_decode(ske->ke1_payload->pk_data, 
                              ske->ke1_payload->pk_len, &idata->public_key);
@@ -919,7 +926,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
 
       SILC_PUT32_MSB(SILC_AUTH_OK, ok);
 
-      /* Authentication failed */
+      /* Authentication successful */
       silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
                              0, ok, 4, TRUE);
 
@@ -986,6 +993,231 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
   }
 }
 
+/*
+ * Re-key protocol routines
+ */
+
+/* This function actually re-generates (when not using PFS) the keys and
+   takes them into use. */
+
+void silc_server_protocol_rekey_generate(SilcServer server,
+                                        SilcServerRekeyInternalContext *ctx)
+{
+  SilcIDListData idata = (SilcIDListData)ctx->sock->user_data;
+  SilcSKEKeyMaterial *keymat;
+  uint32 key_len = silc_cipher_get_key_len(idata->send_key);
+  uint32 hash_len = idata->hash->hash->hash_len;
+
+  SILC_LOG_DEBUG(("Generating new session keys (no PFS)"));
+
+  /* Generate the new key */
+  keymat = silc_calloc(1, sizeof(*keymat));
+  silc_ske_process_key_material_data(idata->rekey->send_enc_key,
+                                    idata->rekey->enc_key_len,
+                                    16, key_len, hash_len, 
+                                    idata->hash, keymat);
+
+  /* Set the keys into use */
+
+  if (ctx->responder == TRUE) {
+    silc_cipher_set_key(idata->send_key, keymat->receive_enc_key, 
+                       keymat->enc_key_len);
+    silc_cipher_set_iv(idata->send_key, keymat->receive_iv);
+    silc_cipher_set_key(idata->receive_key, keymat->send_enc_key, 
+                       keymat->enc_key_len);
+    silc_cipher_set_iv(idata->receive_key, keymat->send_iv);
+  } else {
+    silc_cipher_set_key(idata->send_key, keymat->send_enc_key, 
+                       keymat->enc_key_len);
+    silc_cipher_set_iv(idata->send_key, keymat->send_iv);
+    silc_cipher_set_key(idata->receive_key, keymat->receive_enc_key, 
+                       keymat->enc_key_len);
+    silc_cipher_set_iv(idata->receive_key, keymat->receive_iv);
+  }
+
+  silc_hmac_set_key(idata->hmac, keymat->hmac_key, keymat->hmac_key_len);
+
+  /* Save the current sending encryption key */
+  memset(idata->rekey->send_enc_key, 0, idata->rekey->enc_key_len);
+  silc_free(idata->rekey->send_enc_key);
+  idata->rekey->send_enc_key = 
+    silc_calloc(keymat->enc_key_len / 8,
+               sizeof(*idata->rekey->send_enc_key));
+  memcpy(idata->rekey->send_enc_key, keymat->send_enc_key, 
+        keymat->enc_key_len / 8);
+  idata->rekey->enc_key_len = keymat->enc_key_len / 8;
+
+  silc_ske_free_key_material(keymat);
+}
+
+/* Performs re-key as defined the SILC protocol specification. */
+
+SILC_TASK_CALLBACK(silc_server_protocol_rekey)
+{
+  SilcProtocol protocol = (SilcProtocol)context;
+  SilcServerRekeyInternalContext *ctx = 
+    (SilcServerRekeyInternalContext *)protocol->context;
+  SilcServer server = (SilcServer)ctx->server;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
+    protocol->state = SILC_PROTOCOL_STATE_START;
+
+  SILC_LOG_DEBUG(("State=%d", protocol->state));
+
+  switch(protocol->state) {
+  case SILC_PROTOCOL_STATE_START:
+    {
+      /* 
+       * Start protocol.
+       */
+
+      if (ctx->responder == TRUE) {
+       /*
+        * We are receiving party
+        */
+
+       if (ctx->pfs == TRUE) {
+         /* 
+          * Use Perfect Forward Secrecy, ie. negotiate the key material
+          * using the SKE protocol.
+          */
+
+       } else {
+         /*
+          * Do normal and simple re-key.
+          */
+
+         /* Send the REKEY_DONE to indicate we will take new keys into use */
+         silc_server_packet_send(server, ctx->sock, SILC_PACKET_REKEY_DONE,
+                                 0, NULL, 0, TRUE);
+
+         /* The protocol ends in next stage. */
+         protocol->state = SILC_PROTOCOL_STATE_END;
+       }
+      
+      } else {
+       /*
+        * We are the initiator of this protocol
+        */
+
+       if (ctx->pfs == TRUE) {
+         /* 
+          * Use Perfect Forward Secrecy, ie. negotiate the key material
+          * using the SKE protocol.
+          */
+
+       } else {
+         /*
+          * Do normal and simple re-key.
+          */
+
+         /* Start the re-key by sending the REKEY packet */
+         silc_server_packet_send(server, ctx->sock, SILC_PACKET_REKEY,
+                                 0, NULL, 0, TRUE);
+
+         /* The protocol ends in next stage. */
+         protocol->state = SILC_PROTOCOL_STATE_END;
+       }
+      }
+
+    }
+    break;
+
+  case SILC_PROTOCOL_STATE_END:
+    /* 
+     * End protocol
+     */
+
+    if (ctx->responder == TRUE) {
+
+      if (ctx->pfs == TRUE) {
+       /*
+        *
+        */
+       
+      } else {
+       /*
+        * We must have received the REKEY_DONE from the initiator.
+        */
+
+       if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
+         /* Error in protocol */
+         protocol->state = SILC_PROTOCOL_STATE_ERROR;
+         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
+       }
+      }
+
+    } else {
+
+      if (ctx->pfs == TRUE) {
+       /*
+        *
+        */
+       
+      } else {
+       /*
+        * We must have received the REKEY_DONE from the responder.
+        */
+
+       if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
+         /* Error in protocol */
+         protocol->state = SILC_PROTOCOL_STATE_ERROR;
+         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
+       }
+
+       /* Send the REKEY_DONE to indicate we will take new keys into use 
+          now. */ 
+       silc_server_packet_send(server, ctx->sock, SILC_PACKET_REKEY_DONE,
+                               0, NULL, 0, TRUE);
+      }
+    }
+
+    /* Protocol has ended, call the final callback */
+    if (protocol->final_callback)
+      protocol->execute_final(server->timeout_queue, 0, protocol, fd);
+    else
+      silc_protocol_free(protocol);
+    break;
+
+  case SILC_PROTOCOL_STATE_ERROR:
+    /*
+     * Error occured
+     */
+
+    if (ctx->pfs == TRUE) {
+      /* Send abort notification */
+      silc_ske_abort(ctx->ske, ctx->ske->status, 
+                    silc_server_protocol_ke_send_packet,
+                    context);
+    }
+
+    /* On error the final callback is always called. */
+    if (protocol->final_callback)
+      protocol->execute_final(server->timeout_queue, 0, protocol, fd);
+    else
+      silc_protocol_free(protocol);
+    break;
+
+  case SILC_PROTOCOL_STATE_FAILURE:
+    /*
+     * We have received failure from remote
+     */
+
+    /* On error the final callback is always called. */
+    if (protocol->final_callback)
+      protocol->execute_final(server->timeout_queue, 0, protocol, fd);
+    else
+      silc_protocol_free(protocol);
+    break;
+
+  case SILC_PROTOCOL_STATE_UNKNOWN:
+    break;
+  }
+
+}
+
 /* Registers protocols used in server. */
 
 void silc_server_protocols_register(void)
@@ -994,6 +1226,8 @@ void silc_server_protocols_register(void)
                         silc_server_protocol_connection_auth);
   silc_protocol_register(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
                         silc_server_protocol_key_exchange);
+  silc_protocol_register(SILC_PROTOCOL_SERVER_REKEY,
+                        silc_server_protocol_rekey);
 }
 
 /* Unregisters protocols */
@@ -1004,4 +1238,6 @@ void silc_server_protocols_unregister(void)
                           silc_server_protocol_connection_auth);
   silc_protocol_unregister(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
                           silc_server_protocol_key_exchange);
+  silc_protocol_unregister(SILC_PROTOCOL_SERVER_REKEY,
+                          silc_server_protocol_rekey);
 }
index e26a58e0d1b6b6d42dfefc25d24114a4b187e875..1977bf8aa05c5be282d61aed9e5b61c7b92c46c8 100644 (file)
 #define PROTOCOL_H
 
 /* SILC client protocol types */
-#define SILC_PROTOCOL_SERVER_NONE 0
-#define SILC_PROTOCOL_SERVER_CONNECTION_AUTH 1
-#define SILC_PROTOCOL_SERVER_KEY_EXCHANGE 2
-/* #define SILC_PROTOCOL_SERVER_MAX 255 */
+#define SILC_PROTOCOL_SERVER_NONE               0
+#define SILC_PROTOCOL_SERVER_CONNECTION_AUTH    1
+#define SILC_PROTOCOL_SERVER_KEY_EXCHANGE       2
+#define SILC_PROTOCOL_SERVER_REKEY              3
+/* #define SILC_PROTOCOL_SERVER_MAX             255 */
 
 /* Internal context for Key Exchange protocol. */
 typedef struct {
@@ -35,7 +36,7 @@ typedef struct {
   SilcRng rng;
 
   /* TRUE if we are receiveing part of the protocol */
-  int responder;
+  bool responder;
 
   /* Destinations ID taken from authenticataed packet so that we can
      get the destinations ID. */
@@ -55,7 +56,7 @@ typedef struct {
   SilcSocketConnection sock;
 
   /* TRUE if we are receiving part of the protocol */
-  int responder;
+  bool responder;
 
   /* SKE object from Key Exchange protocol. */
   SilcSKE ske;
@@ -80,6 +81,18 @@ typedef struct {
   uint16 conn_type;
 } SilcServerConnAuthInternalContext;
 
+/* Internal context for the rekey protocol */
+typedef struct {
+  void *server;
+  void *context;
+  SilcSocketConnection sock;
+  bool responder;                  /* TRUE if we are receiving party */
+  bool pfs;                        /* TRUE if PFS is to be used */
+  SilcSKE ske;                     /* Defined if PFS is used */
+  SilcSKEKeyMaterial *keymat;      /* Defined if PFS is used */
+  SilcPacketContext *packet;
+} SilcServerRekeyInternalContext;
+
 /* Prototypes */
 void silc_server_protocols_register(void);
 void silc_server_protocols_unregister(void);
@@ -90,6 +103,8 @@ int silc_server_protocol_ke_set_keys(SilcSKE ske,
                                     SilcPKCS pkcs,
                                     SilcHash hash,
                                     SilcHmac hmac,
-                                    int is_responder);
+                                    bool is_responder);
+void silc_server_protocol_rekey_generate(SilcServer server,
+                                        SilcServerRekeyInternalContext *ctx);
 
 #endif
index 3ef616134ee65a1d55860cbad94b33b55c2691e0..1ba577a403e9e11106c0b27bcac287a30e74f475 100644 (file)
@@ -39,6 +39,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process);
 SILC_TASK_CALLBACK(silc_server_packet_parse_real);
 SILC_TASK_CALLBACK(silc_server_timeout_remote);
 SILC_TASK_CALLBACK(silc_server_failure_callback);
+SILC_TASK_CALLBACK(silc_server_rekey_callback);
 
 /* Allocates a new SILC server object. This has to be done before the server
    can be used. After allocation one must call silc_server_init to initialize
@@ -709,7 +710,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
     (SilcServerKEInternalContext *)protocol->context;
   SilcServer server = (SilcServer)ctx->server;
   SilcServerConnection sconn = (SilcServerConnection)ctx->context;
-  SilcSocketConnection sock = NULL;
+  SilcSocketConnection sock = server->sockets[fd];
   SilcServerConnAuthInternalContext *proto_ctx;
   SilcServerConfigSectionServerConnection *conn = NULL;
 
@@ -719,6 +720,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
     /* Error occured during protocol */
     silc_protocol_free(protocol);
+    sock->protocol = NULL;
     silc_ske_free_key_material(ctx->keymat);
     if (ctx->packet)
       silc_packet_context_free(ctx->packet);
@@ -744,6 +746,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
                                        ctx->ske->prop->hmac,
                                        ctx->responder)) {
     silc_protocol_free(protocol);
+    sock->protocol = NULL;
     silc_ske_free_key_material(ctx->keymat);
     if (ctx->packet)
       silc_packet_context_free(ctx->packet);
@@ -765,7 +768,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
   proto_ctx->server = (void *)server;
   proto_ctx->context = (void *)sconn;
-  proto_ctx->sock = sock = server->sockets[fd];
+  proto_ctx->sock = sock;
   proto_ctx->ske = ctx->ske;      /* Save SKE object from previous protocol */
   proto_ctx->dest_id_type = ctx->dest_id_type;
   proto_ctx->dest_id = ctx->dest_id;
@@ -786,6 +789,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
     SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
                    sock->hostname, sock->ip, sock->port));
     silc_protocol_free(protocol);
+    sock->protocol = NULL;
     if (ctx->packet)
       silc_packet_context_free(ctx->packet);
     if (ctx->ske)
@@ -845,6 +849,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   SilcBuffer packet;
   SilcServerHBContext hb_context;
   unsigned char *id_string;
+  SilcIDListData idata;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -909,7 +914,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   sock->type = SILC_SOCKET_TYPE_ROUTER;
   server->id_entry->router = id_entry;
   server->router = id_entry;
-  server->router->data.registered = TRUE;
+  idata = (SilcIDListData)sock->user_data;
+  idata->registered = TRUE;
 
   /* Perform keepalive. The `hb_context' will be freed automatically
      when finally calling the silc_socket_free function. XXX hardcoded 
@@ -920,6 +926,14 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
                            silc_server_perform_heartbeat,
                            server->timeout_queue);
 
+  /* Register re-key timeout */
+  idata->rekey->timeout = 60; /* XXX hardcoded */
+  idata->rekey->context = (void *)server;
+  silc_task_register(server->timeout_queue, sock->sock, 
+                    silc_server_rekey_callback,
+                    (void *)sock, idata->rekey->timeout, 0,
+                    SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+
   /* If we are router then announce our possible servers. */
   if (server->server_type == SILC_ROUTER)
     silc_server_announce_servers(server);
@@ -1049,7 +1063,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
   SilcServerKEInternalContext *ctx = 
     (SilcServerKEInternalContext *)protocol->context;
   SilcServer server = (SilcServer)ctx->server;
-  SilcSocketConnection sock = NULL;
+  SilcSocketConnection sock = server->sockets[fd];
   SilcServerConnAuthInternalContext *proto_ctx;
 
   SILC_LOG_DEBUG(("Start"));
@@ -1058,6 +1072,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
     /* Error occured during protocol */
     silc_protocol_free(protocol);
+    sock->protocol = NULL;
     silc_ske_free_key_material(ctx->keymat);
     if (ctx->packet)
       silc_packet_context_free(ctx->packet);
@@ -1084,6 +1099,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
                                        ctx->ske->prop->hmac,
                                        ctx->responder)) {
     silc_protocol_free(protocol);
+    sock->protocol = NULL;
     silc_ske_free_key_material(ctx->keymat);
     if (ctx->packet)
       silc_packet_context_free(ctx->packet);
@@ -1105,7 +1121,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
      is sent as context for the protocol. */
   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
   proto_ctx->server = (void *)server;
-  proto_ctx->sock = sock = server->sockets[fd];
+  proto_ctx->sock = sock;
   proto_ctx->ske = ctx->ske;   /* Save SKE object from previous protocol */
   proto_ctx->responder = TRUE;
   proto_ctx->dest_id_type = ctx->dest_id_type;
@@ -1157,6 +1173,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
     /* Error occured during protocol */
     silc_protocol_free(protocol);
+    sock->protocol = NULL;
     if (ctx->packet)
       silc_packet_context_free(ctx->packet);
     if (ctx->ske)
@@ -1902,6 +1919,46 @@ void silc_server_packet_parse_type(SilcServer server,
     silc_server_key_agreement(server, sock, packet);
     break;
 
+  case SILC_PACKET_REKEY:
+    /*
+     * Received re-key packet. The sender wants to regenerate the session
+     * keys.
+     */
+    SILC_LOG_DEBUG(("Re-key packet"));
+    if (packet->flags & SILC_PACKET_FLAG_LIST)
+      break;
+    silc_server_rekey(server, sock, packet);
+    break;
+
+  case SILC_PACKET_REKEY_DONE:
+    /*
+     * The re-key is done.
+     */
+    SILC_LOG_DEBUG(("Re-key done packet"));
+    if (packet->flags & SILC_PACKET_FLAG_LIST)
+      break;
+
+    if (sock->protocol && sock->protocol->protocol &&
+       sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
+
+      SilcServerRekeyInternalContext *proto_ctx = 
+       (SilcServerRekeyInternalContext *)sock->protocol->context;
+
+      if (proto_ctx->packet)
+       silc_packet_context_free(proto_ctx->packet);
+
+      proto_ctx->packet = silc_packet_context_dup(packet);
+
+      /* Let the protocol handle the packet */
+      sock->protocol->execute(server->timeout_queue, 0, 
+                             sock->protocol, sock->sock,
+                             0, 100000);
+    } else {
+      SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
+                     "protocol active, packet dropped."));
+    }
+    break;
+
   default:
     SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
     break;
@@ -3541,3 +3598,88 @@ SilcClientEntry silc_server_get_client_resolve(SilcServer server,
 
   return client;
 }
+
+/* A timeout callback for the re-key. We will be the initiator of the
+   re-key protocol. */
+
+SILC_TASK_CALLBACK(silc_server_rekey_callback)
+{
+  SilcSocketConnection sock = (SilcSocketConnection)context;
+  SilcIDListData idata = (SilcIDListData)sock->user_data;
+  SilcServer server = (SilcServer)idata->rekey->context;
+  SilcProtocol protocol;
+  SilcServerRekeyInternalContext *proto_ctx;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  /* Allocate internal protocol context. This is sent as context
+     to the protocol. */
+  proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
+  proto_ctx->server = (void *)server;
+  proto_ctx->sock = sock;
+  proto_ctx->responder = FALSE;
+      
+  /* Perform rekey protocol. Will call the final callback after the
+     protocol is over. */
+  silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
+                     &protocol, proto_ctx, silc_server_rekey_final);
+  sock->protocol = protocol;
+      
+  /* Run the protocol */
+  protocol->execute(server->timeout_queue, 0, protocol, 
+                   sock->sock, 0, 0);
+
+  /* Re-register re-key timeout */
+  silc_task_register(server->timeout_queue, sock->sock, 
+                    silc_server_rekey_callback,
+                    context, idata->rekey->timeout, 0,
+                    SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+}
+
+/* The final callback for the REKEY protocol. This will actually take the
+   new key material into use. */
+
+SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
+{
+  SilcProtocol protocol = (SilcProtocol)context;
+  SilcServerRekeyInternalContext *ctx =
+    (SilcServerRekeyInternalContext *)protocol->context;
+  SilcServer server = (SilcServer)ctx->server;
+  SilcSocketConnection sock = ctx->sock;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
+      protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
+    /* Error occured during protocol */
+    silc_protocol_free(protocol);
+    sock->protocol = NULL;
+    if (ctx->keymat)
+      silc_ske_free_key_material(ctx->keymat);
+    if (ctx->packet)
+      silc_packet_context_free(ctx->packet);
+    if (ctx->ske)
+      silc_ske_free(ctx->ske);
+    silc_free(ctx);
+    return;
+  }
+
+  /* Take the keys into use */
+  if (ctx->pfs == TRUE) {
+
+  } else {
+    /* Then just generate the new keys and take them into use */
+    silc_server_protocol_rekey_generate(server, ctx);
+  }
+
+  /* Cleanup */
+  silc_protocol_free(protocol);
+  sock->protocol = NULL;
+  if (ctx->keymat)
+    silc_ske_free_key_material(ctx->keymat);
+  if (ctx->packet)
+    silc_packet_context_free(ctx->packet);
+  if (ctx->ske)
+    silc_ske_free(ctx->ske);
+  silc_free(ctx);
+}
index 93d046ad6ea5adb7f29e9884aefb9b4d3876b518..bc215e07da8db9358021808434226b094048ab06 100644 (file)
    various things. */
 typedef struct {
   /* Local stats (server and router) */
-  uint32 my_clients;     /* Locally connected clients */
-  uint32 my_servers;     /* Locally connected servers */
-  uint32 my_routers;     /* Locally connected routers */
-  uint32 my_channels;    /* Locally created channels */
+  uint32 my_clients;             /* Locally connected clients */
+  uint32 my_servers;             /* Locally connected servers */
+  uint32 my_routers;             /* Locally connected routers */
+  uint32 my_channels;            /* Locally created channels */
   uint32 my_chanclients;         /* Local clients on local channels */
-  uint32 my_aways;       /* Local clients away (XXX) */
-  uint32 my_server_ops;          /* Local server operators */
-  uint32 my_router_ops;          /* Local router operators */
+  uint32 my_aways;               /* Local clients away (XXX) */
+  uint32 my_server_ops;                  /* Local server operators */
+  uint32 my_router_ops;                  /* Local router operators */
 
   /* Global stats (mainly for router) */
-  uint32 cell_clients;   /* All clients in cell */
-  uint32 cell_servers;   /* All servers in cell */
-  uint32 cell_channels;          /* All channels in cell */
-  uint32 cell_chanclients; /* All clients on cell's channels */
-  uint32 clients;        /* All clients */
-  uint32 servers;        /* All servers */
-  uint32 routers;        /* All routers */
-  uint32 channels;       /* All channels */
-  uint32 chanclients;    /* All clients on channels */
-  uint32 server_ops;     /* All server operators */
-  uint32 router_ops;     /* All router operators */
+  uint32 cell_clients;           /* All clients in cell */
+  uint32 cell_servers;           /* All servers in cell */
+  uint32 cell_channels;                  /* All channels in cell */
+  uint32 cell_chanclients;       /* All clients on cell's channels */
+  uint32 clients;                /* All clients */
+  uint32 servers;                /* All servers */
+  uint32 routers;                /* All routers */
+  uint32 channels;               /* All channels */
+  uint32 chanclients;            /* All clients on channels */
+  uint32 server_ops;             /* All server operators */
+  uint32 router_ops;             /* All router operators */
 
   /* General */
-  uint32 conn_attempts;          /* Connection attempts */
-  uint32 conn_failures;          /* Connection failure */
-  uint32 auth_attempts;          /* Authentication attempts */
-  uint32 auth_failures;          /* Authentication failures */
-  uint32 packets_sent;   /* Sent packets */
-  uint32 packets_received; /* Received packets */
+  uint32 conn_attempts;                  /* Connection attempts */
+  uint32 conn_failures;                  /* Connection failure */
+  uint32 auth_attempts;                  /* Authentication attempts */
+  uint32 auth_failures;                  /* Authentication failures */
+  uint32 packets_sent;           /* Sent packets */
+  uint32 packets_received;       /* Received packets */
 } SilcServerStatistics;
 
 typedef struct {
@@ -187,5 +187,6 @@ do {                                                                        \
 } while(0)
 
 /* Prototypes */
+SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final);
 
 #endif
index 34dbe96ccdab111e72a374420d4f53f5ce434953..0a63644baaccef54a6b2a35b1d572b2d1622bb6c 100644 (file)
@@ -134,7 +134,7 @@ This document refers constantly to other SILC protocol specification
 Internet Drafts that are a must read for those who wants to understand
 the function of these protocols.  The most important references are
 the Secure Internet Live Conferencing, Protocol Specification [SILC1]
-and SILC Packet Protocol [SILC2] Internet Drafts.
+and the SILC Packet Protocol [SILC2] Internet Drafts.
 
 The protocol is intended to be used with the SILC protocol thus it
 does not define own framework that could be used.  The framework is
@@ -158,7 +158,7 @@ The purpose of SILC Key Exchange protocol is to create session keys to
 be used in current SILC session.  The keys are valid only for some period
 of time (usually an hour) or at most until the session ends.  These keys
 are used to protect packets like commands, command replies and other
-communication between two entities.  If connection is server to server
+communication between two entities.  If connection is server to router
 connection, the keys are used to protect all traffic between those
 servers.  In client connections usually all the packets are protected
 with this key except channel messages; channels has their own keys and 
@@ -195,16 +195,14 @@ by responder must include only one chosen property per list.
 
 The Key Exchange Start Payload is used to tell connecting entities what
 security properties and algorithms should be used in the communication.
-If perfect forward secrecy (PFS) is not desired (PFS is undefined by
-default) Key Exchange Start Payload is sent only once per session, thus,
-for example, re-keying will not cause sending of a new payload.  If PFS
-is desired, re-keying will always cause new key exchange thus causes
-sending of a new Key Exchange Start Payload.
+The Key Exchange Start Payload is sent only once per session.  Even if
+the PFS (Perfect Forward Secrecy) flag is se the Key Exchange Start Payload
+is not re-sent.   When PFS is desired the Key Exchange Payloads are sent
+to negotiate new key material.  The procedure is equivalent to the very
+first negotiation except that the Key Exchange Start Payload is not sent.
 
-When performing first key exchange this payload is never encrypted, as
-there are no existing keys to encrypt it with.  If performing re-keying
-(PFS was selected) this payload is encrypted with the existing key and
-encryption algorithm.
+As this payload is used only with the very first key exchnage the payload
+is never encrypted, as there are no keys to encrypt it with.
 
 A cookie is also sent in this payload.  A cookie is used to uniform the
 payload so that none of the key exchange parties can determine this
@@ -307,12 +305,15 @@ o Flags (1 byte) - Indicates flags to be used in the key
 
        Perfect Forward Secrecy (PFS) to be used in the
        key exchange protocol.  If not set, re-keying
-       is performed using the old key.  When PFS is used, 
+       is performed using the old key.  See the [SILC1]
+       for more information on this issue.  When PFS is used, 
        re-keying and creating new keys for any particular 
-       purpose will cause new key exchange.
-
-       Rest of the flags are reserved for the future and
-       must not be set.
+       purpose will cause new key exchange.  In this key
+       exchange only the Key Exchange Payload is sent and
+       the Key Exchange Start Payload must not be sent.
+       When doing PFS the Key Exchange Payloads are 
+       encrypted with the old keys.  With the PFS, the
+       Mutual Authentication flag must be ignored.
 
      Mutual Authentication    0x04
 
@@ -324,6 +325,9 @@ o Flags (1 byte) - Indicates flags to be used in the key
        set this but also responder may set this even if
        initiator did not set it.
 
+     Rest of the flags are reserved for the future and
+     must not be set.
+
 o Payload Length (2 bytes) - Length of the entire Key Exchange
   Start payload, not including any other field.
 
@@ -488,7 +492,7 @@ o Signature Data (variable length) - The signature signed
 
 The key exchange begins by sending SILC_PACKET_KEY_EXCHANGE packet with
 Key Exchange Start Payload to select the security properties to be used
-in the key exchange and later in the  communication.
+in the key exchange and later in the communication.
 
 After Key Exchange Start Payload has been processed by both of the
 parties the protocol proceeds as follows:
@@ -651,7 +655,7 @@ first group diffie-hellman-group1 is mandatory, other groups maybe
 negotiated to be used in the connection with Key Exchange Start Payload
 and SILC_PACKET_KEY_EXCHANGE packet.  However, the first group must be
 proposed in the Key Exchange Start Payload regardless of any other
-requested group (however, it does not have to be the first on the list).
+requested group (however, it does not have to be the first in the list).
 
 
 .ti 0
@@ -683,7 +687,7 @@ FFFFFFFF FFFFFFFF
 .in 3
 
 
-The generator used with this prime is g = 2. The group order q is
+The generator used with this prime is g = 2.  The group order q is
 (p - 1) / 2.
 
 This group was taken from the OAKLEY specification.
@@ -721,7 +725,7 @@ C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
 670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF
 .in 3
 
-The generator used with this prime is g = 2. The group order q is
+The generator used with this prime is g = 2.  The group order q is
 (p - 1) / 2.
 
 This group was taken from the OAKLEY specification.
@@ -735,7 +739,7 @@ returned in the SILC_PACKET_SUCCESS or SILC_PACKET_FAILURE packets to
 indicate the status of the protocol.  Implementations may map the
 status types to human readable error message.  All types except the
 SILC_SKE_STATUS_OK type must be sent in SILC_PACKET_FAILURE packet.
-The length of status is 32 bits (4 bytes). Following status types are 
+The length of status is 32 bits (4 bytes).  Following status types are 
 defined:
 
 .in 6
@@ -789,7 +793,7 @@ defined:
     Provided signature was incorrect.
 
 
-10   SILC_SKE_STATUS_BAD_VERSION
+10  SILC_SKE_STATUS_BAD_VERSION
 
     Provided version string was not acceptable.
 .in 3
@@ -1059,5 +1063,4 @@ Finland
 
 EMail: priikone@poseidon.pspt.fi
 
-This Internet-Draft expires 6 Jun 2001 
-
+This Internet-Draft expires 6 Jun 2001
\ No newline at end of file
index 1e734c3363a394934ed9ee31d1201982b6e23e0f..03d1f40e1165c20d4b3fe247418d2b041a442360 100644 (file)
@@ -111,7 +111,6 @@ Table of Contents
   2.10 Packet Reception ......................................... 43
   2.11 Packet Routing ........................................... 44
   2.12 Packet Broadcasting ...................................... 45
-  2.13 Packet Tunneling ......................................... 45
 3 Security Considerations ....................................... 46
 4 References .................................................... 46
 5 Author's Address .............................................. 47
@@ -315,14 +314,6 @@ o Flags (1 byte) - Indicates flags to be used in packet
        section 2.13 Packet Broadcasting for description of 
        packet broadcasting.
 
-
-     Tunneled                  0x08
-
-       Marks that the packet is tunneled.  Tunneling means
-       that extra SILC Packet Header has been applied to the
-       original packet.  The outer header has this flag
-       set.  See section 2.14 Packet Tunneling for more
-       information.
 .in 3
 
 
@@ -2558,24 +2549,6 @@ about newly registered clients, servers, channels etc. so that all the
 routers may keep these informations up to date.
 
 
-.ti 0
-2.13 Packet Tunneling
-
-Tunneling is a feature that is available in SILC protocol.  Tunneling
-means that extra SILC Packet Header is applied to the original packet
-and thus hiding the original packet entirely.  There can be some
-interesting applications using tunneling, such as, using ID's based on
-private network IP addresses inside in the tunneled packet.  This can
-open many interesting features relating to connecting to private network
-from the Internet with SILC and many more.  However, this feature is
-optional currently in SILC as there does not exist thorough analysis of
-this feature.  It is with out a doubt that there will be many more
-applications that has not yet been discovered.  Thus, it is left
-to Internet Community to investigate the use of tunneling in SILC
-protocol.  This document is updated according those investigations
-and additional documents on the issue may be written.
-
-
 .ti 0
 3 Security Considerations
 
index 6c6f800d6eba1df6f6ba77d8bcee57a3b17e8037..734a32c30fc9fec94068e162df608a4fd86a8e33 100644 (file)
@@ -1777,7 +1777,8 @@ process.
 
 Session keys should be regenerated periodically, say, once in an hour.
 The re-key process is started by sending SILC_PACKET_REKEY packet to
-other end, to indicate that re-key must be performed.
+other end, to indicate that re-key must be performed.  The initiator
+of the connection should perform the re-key.
 
 If perfect forward secrecy (PFS) flag was selected in the SILC Key
 Exchange protocol [SILC3] the re-key must cause new key exchange with
@@ -1788,13 +1789,17 @@ will perform the SKE protocol.
 
 If PFS flag was not set, which is the default case, then re-key is done
 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.
+providing the current sending encryption key to the SKE protocol's key
+processing function.  The process is described in the section Processing
+the Key Material in [SILC3].  The difference in the processing is that
+the initial data for the hash function is the current sending encryption
+key and not the SKE's KEY and HASH values.  Other than that, the key
+processing is equivalent to normal SKE negotiation.
+
+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 subsequent packets
+must be protected with the new key.
 
 
 .ti 0
index 7bc8a8a9d9724baeb59cdd919fec094f6923fa3b..30a9cc51d65300ea6fd8d7a98bab213bee3f0cd0 100644 (file)
@@ -61,8 +61,8 @@ typedef unsigned char SilcPacketFlags;
 #define SILC_PACKET_FLAG_PRIVMSG_KEY      0x01
 #define SILC_PACKET_FLAG_LIST             0x02
 #define SILC_PACKET_FLAG_BROADCAST        0x04
-#define SILC_PACKET_FLAG_TUNNELED         0x08
 /* Rest of flags still available
+#define SILC_PACKET_FLAG_XXX              0x08
 #define SILC_PACKET_FLAG_XXX              0x10
 #define SILC_PACKET_FLAG_XXX              0x20
 #define SILC_PACKET_FLAG_XXX              0x40