updates.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 27 Feb 2001 14:47:41 +0000 (14:47 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 27 Feb 2001 14:47:41 +0000 (14:47 +0000)
CHANGES
doc/draft-riikonen-silc-pp-01.nroff
doc/draft-riikonen-silc-spec-01.nroff
lib/silcclient/command.c
lib/silcclient/command.h
lib/silcclient/silcapi.h

diff --git a/CHANGES b/CHANGES
index 77481f17141d1f0f30cafc030acab683c16e6bb3..3936b9d13b21d72d2af7bf102dfa92a2c76378dc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -11,6 +11,9 @@ Tue Feb 27 13:30:52 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
          SILC Client Library.  Other files need not be included by
          the application anymore.
 
+       * Added new key_agreement client callback and also defined the
+         Key Agreement library API for the application.
+
 Tue Feb 27 11:28:31 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Added new packet type: SILC_PACKET_KEY_AGREEMENT.  This packet
index 7441119604f81eec225778cf3baa0c2d18624d19..0fa63ff2ed3928e013a014f874a6a8a874121b8e 100644 (file)
@@ -1562,6 +1562,7 @@ o Private Message Key (variable length) - The actual private
 .in 3
 
 
+
 .ti 0
 2.3.13 Command Payload
 
@@ -1967,6 +1968,16 @@ o Port (4 bytes) - The port where the SKE protocol is bound.
 .in 3
 
 
+After the key material has been received from the SKE protocol it is
+processed as the [SILC3] describes.  If the key material is used as
+channel private key then the Sending Encryption Key, as defined in
+[SILC3] is used as the channel private key.  Other key material must
+be discarded.  If the key material is used as private message key then
+the keys and the IV's are used as defined in the [SILC3].  The HMAC
+key, however, must be discarded.  Any other use for the key material
+is undefined.
+
+
 .ti 0
 2.4 SILC ID Types
 
index 85f6b1012cf83c0884be4e007d9dcfebcfa42c13..d31621949614bdc5a5566c35784b04c6e2e6fb05 100644 (file)
@@ -1639,21 +1639,20 @@ may be generated and sent to the other client by sending packet
 SILC_PACKET_PRIVATE_MESSAGE_KEY which travels through the network
 and is secured by session keys.  After that the private message key
 is used in the private message communication between those clients.
-See more information about how this works technically in [SILC2].
 
 Other choice is to entirely use keys that are not sent through
 the SILC network at all.  This significantly adds security.  This key
 would be pre-shared-key that is known by both of the clients.  Both
 agree about using the key and starts sending packets that indicate
-that the private message is secured using private message key.  This
-is the technical aspect mentioned previously that is described
-in [SILC2].
-
-If the private message keys are not set to be used, which is the
-case by default in SILC, the private messages are secured by using
-normal session keys established by SILC Key Exchange protocol.
-
-
+that the private message is secured using private message key.
+
+The key material used as private message key is implementation issue.
+However, SILC_PACKET_KEY_AGREEMENT packet may be used to negotiate
+the key material.  If the key is normal pre-shared-key or randomly
+generated key, and the SILC_PACKET_KEY_AGREEMENT was not used, then
+the key material should be processed as defined in the [SILC3].  After
+processing the key material it is employed as defined in [SILC3],
+however, the HMAC key material must be discarded.
 
 
 .ti 0
index 24406e0bfa428da264e48e2546da6e9ac2662bfc..733072c5ee2a01693086e64fbebcaf97ab2d2abd 100644 (file)
@@ -75,7 +75,7 @@ SilcClientCommand silc_command_list[] =
   cmd, FALSE, cmd->command->cmd)
 
 /* Generic function to send any command. The arguments must be sent already
-   encoded into correct form in correct order. */
+   encoded into correct form and in correct order. */
 
 void silc_client_send_command(SilcClient client, SilcClientConnection conn,
                              SilcCommand command, unsigned short ident,
@@ -201,8 +201,7 @@ void silc_client_command_free(SilcClientCommandContext ctx)
 /* Duplicate Command Context by adding reference counter. The context won't
    be free'd untill it hits zero. */
 
-SilcClientCommandContext 
-silc_client_command_dup(SilcClientCommandContext ctx)
+SilcClientCommandContext silc_client_command_dup(SilcClientCommandContext ctx)
 {
   ctx->users++;
   SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users - 1,
index d36ae1305277a11ed695abf50e5e0dd161269f6e..1954d4578347ec6f0582c97d1bed0766d6a809dd 100644 (file)
@@ -59,7 +59,10 @@ typedef struct {
 /* All client commands */
 extern SilcClientCommand silc_command_list[];
 
-/* Context sent as argument to all commands */
+/* Context sent as argument to all commands. This is used by the library
+   and application should use this as well. However, application may
+   choose to use some own context for its own local command. All library
+   commands, however, must use this context. */
 typedef struct {
   SilcClient client;
   SilcClientConnection conn;
@@ -72,12 +75,7 @@ typedef struct {
   int users;                   /* Reference counter */
 } *SilcClientCommandContext;
 
-/* Pending Command callback destructor. This is called after calling the
-   pending callback or if error occurs while processing the pending command.
-   If error occurs then the callback won't be called at all, and only this
-   destructor is called. The `context' is the context given for the function
-   silc_client_command_pending. */
-typedef void (*SilcClientPendingDestructor)(void *context);
+#include "silcapi.h"
 
 /* Structure holding pending commands. If command is pending it will be
    executed after command reply has been executed. */
@@ -121,21 +119,7 @@ do {                                                                       \
     (*ctx->destructor)(ctx->context);                                  \
 } while(0)
 
-/* Prototypes */
-void silc_client_send_command(SilcClient client, SilcClientConnection conn,
-                             SilcCommand command, unsigned short ident,
-                             unsigned int argc, ...);
-SilcClientCommand *silc_client_command_find(const char *name);
-SilcClientCommandContext silc_client_command_alloc();
-void silc_client_command_free(SilcClientCommandContext ctx);
-SilcClientCommandContext 
-silc_client_command_dup(SilcClientCommandContext ctx);
-void silc_client_command_pending(SilcClientConnection conn,
-                                SilcCommand reply_cmd,
-                                unsigned short ident,
-                                SilcClientPendingDestructor destructor,
-                                SilcCommandCb callback,
-                                void *context);
+/* Prototypes (some prototypes are in the silcapi.h file) */
 void silc_client_command_pending_del(SilcClientConnection conn,
                                     SilcCommand reply_cmd,
                                     unsigned short ident);
index c67a969f0a2f34145df5f4e195c7ad459515cc7b..e91929c90608a31fb30565c80d003274c7b19c71 100644 (file)
@@ -151,6 +151,15 @@ typedef struct {
      types). */
   void (*failure)(SilcClient client, SilcClientConnection conn, 
                  SilcProtocol protocol, void *failure);
+
+  /* Asks whether the user would like to perform the key agreement protocol.
+     This is called after we have received an key agreement packet or an
+     reply to our key agreement packet. This returns TRUE if the user wants
+     the library to perform the key agreement protocol and FALSE if it is not
+     desired. */
+  int (*key_agreement)(SilcClient client, SilcClientConnection conn,
+                      SilcClientEntry client_entry, char *hostname,
+                      int port);
 } SilcClientOperations;
 
 
@@ -233,7 +242,7 @@ void silc_client_close_connection(SilcClient client,
                                  SilcClientConnection conn);
 
 
-/* Packet sending functions */
+/* Message sending functions */
 
 /* Sends packet to the `channel'. Packet to channel is always encrypted
    differently from "normal" packets. SILC header of the packet is 
@@ -263,14 +272,108 @@ void silc_client_send_private_message(SilcClient client,
                                      int force_send);
 
 
+/* Client and Channel entry retrieval */
+
+/* Callback function given to the silc_client_get_client function. The
+   found entries are allocated into the `clients' array. The array must
+   not be freed by the caller, the library will free it later. If the
+   `clients' is NULL, no such clients exist in the SILC Network. */
+typedef void (*SilcGetClientCallback)(SilcClient client,
+                                     SilcClientConnection conn,
+                                     SilcClientEntry *clients,
+                                     unsigned int clients_count,
+                                     void *context);
+
+/* Finds client entry or entries by the `nickname' and `server'. The 
+   completion callback will be called when the client entries has been found.
+
+   Note: this function is always asynchronous and resolves the client
+   information from the server. Thus, if you already know the client
+   information then use the silc_client_get_client_by_id function to
+   get the client entry since this function may be very slow and should
+   be used only to initially get the client entries. */
+void silc_client_get_clients(SilcClient client,
+                            SilcClientConnection conn,
+                            char *nickname,
+                            char *server,
+                            SilcGetClientCallback completion,
+                            void *context);
+
+/* Same as above function but does not resolve anything from the server.
+   This checks local cache and returns all clients from the cache. */
+SilcClientEntry *silc_client_get_clients_local(SilcClient client,
+                                              SilcClientConnection conn,
+                                              char *nickname,
+                                              char *server,
+                                              unsigned int *clients_count);
+
+/* Find entry for client by the client's ID. Returns the entry or NULL
+   if the entry was not found. */
+SilcClientEntry silc_client_get_client_by_id(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcClientID *client_id);
+
+/* Finds entry for channel by the channel name. Returns the entry or NULL
+   if the entry was not found. It is found only if the client is joined
+   to the channel. */
+SilcChannelEntry silc_client_get_channel(SilcClient client,
+                                        SilcClientConnection conn,
+                                        char *channel);
+
+
+/* Command management */
+
+/* Allocate Command Context. The context is defined in `command.h' file.
+   The context is used by the library commands and applications should use
+   it as well. However, application may choose to use some own context
+   for its local commands. All library commands, however, must use this
+   context. */
+SilcClientCommandContext silc_client_command_alloc();
+
+/* Free command context and its internals */
+void silc_client_command_free(SilcClientCommandContext ctx);
+
+/* Duplicate Command Context by adding reference counter. The context won't
+   be free'd untill it hits zero. */
+SilcClientCommandContext silc_client_command_dup(SilcClientCommandContext ctx);
+
+/* Finds and returns a pointer to the command list. Return NULL if the
+   command is not found. See the `command.[ch]' for the command list. */
+SilcClientCommand *silc_client_command_find(const char *name);
+
+/* Generic function to send any command. The arguments must be sent already
+   encoded into correct form and in correct order. */
+void silc_client_send_command(SilcClient client, SilcClientConnection conn,
+                             SilcCommand command, unsigned short ident,
+                             unsigned int argc, ...);
+
+/* Pending Command callback destructor. This is called after calling the
+   pending callback or if error occurs while processing the pending command.
+   If error occurs then the callback won't be called at all, and only this
+   destructor is called. The `context' is the context given for the function
+   silc_client_command_pending. */
+typedef void (*SilcClientPendingDestructor)(void *context);
+
+/* Add new pending command to be executed when reply to a command has been
+   received.  The `reply_cmd' is the command that will call the `callback'
+   with `context' when reply has been received.  If `ident is non-zero
+   the `callback' will be executed when received reply with command 
+   identifier `ident'. */
+void silc_client_command_pending(SilcClientConnection conn,
+                                SilcCommand reply_cmd,
+                                unsigned short ident,
+                                SilcClientPendingDestructor destructor,
+                                SilcCommandCb callback,
+                                void *context);
+
+
 /* Private Message key management */
 
 /* Adds private message key to the client library. The key will be used to
    encrypt all private message between the client and the remote client
-   indicated by the `client_entry'.  If `key' is NULL and the boolean value
-   `generate_key' is TRUE then the library will generate random key.  
-   Otherwise the `key' provided by the application will be used.  It maybe
-   random key or pre-shared-key.
+   indicated by the `client_entry'. If the `key' is NULL and the boolean
+   value `generate_key' is TRUE the library will generate random key.
+   The `key' maybe for example pre-shared-key, passphrase or similar.
 
    It is not necessary to set key for normal private message usage. If the
    key is not set then the private messages are encrypted using normal
@@ -289,6 +392,14 @@ int silc_client_add_private_message_key(SilcClient client,
                                        unsigned int key_len,
                                        int generate_key);
 
+/* Same as above but takes the key material from the SKE key material
+   structure. This structure is received if the application uses the
+   silc_client_send_key_agreement to negotiate the key material. */
+int silc_client_add_private_message_key_ske(SilcClient client,
+                                           SilcClientConnection conn,
+                                           SilcClientConnection client_entry,
+                                           SilcSKEKeyMaterial *key);
+
 /* Removes the private message from the library. The key won't be used
    after this to protect the private messages with the remote `client_entry'
    client. Returns FALSE on error, TRUE otherwise. */
@@ -298,12 +409,14 @@ int silc_client_del_private_message_key(SilcClient client,
 
 /* Structure to hold the list of private message keys. The array of this
    structure is returned by the silc_client_list_private_message_keys
-   function.  */
+   function. */
 typedef struct {
   SilcClientEntry client_entry;       /* The remote client entry */
-  unsigned char *key;                /* The raw key data */
+  unsigned char *key;                /* The original key, If the appliation
+                                        provided it. This is NULL if the
+                                        library generated the key or if
+                                        the SKE key material was used. */
   unsigned int key_len;                      /* The key length */
-  int generated;                     /* TRUE if library generated the key */
 } *SilcPrivateMessageKeys;
 
 /* Returns array of set private message keys associated to the connection
@@ -324,7 +437,7 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
                                           unsigned int key_count);
 
 
-/* Channel Message (private) key management */
+/* Channel private key management */
 
 /* Adds private key for channel. This may be set only if the channel's mode
    mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
@@ -343,8 +456,14 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
    be tried in order to find the correct decryption key. However, setting
    a few keys does not have big impact to the decryption performace. 
 
-   Note that this is entirely local setting. The key set using this function
-   is not sent to the network at any phase. */
+   NOTE: that this is entirely local setting. The key set using this function
+   is not sent to the network at any phase.
+
+   NOTE: If the key material was originated by the SKE protocol (using
+   silc_client_send_key_agreement) then the `key' MUST be the
+   key->send_enc_key as this is dictated by the SILC protocol. However,
+   currently it is not expected that the SKE key material would be used
+   as channel private key. However, this API allows it. */
 int silc_client_add_channel_private_key(SilcClient client,
                                        SilcClientConnection conn,
                                        SilcChannelEntry channel,
@@ -390,52 +509,65 @@ void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
                                           unsigned int key_count);
 
 
-/* Client and Channel entry retrieval */
+/* Key Agreement routines */
 
-/* Callback function given to the silc_client_get_client function. The
-   found entries are allocated into the `clients' array. The array must
-   not be freed by the caller, the library will free it later. If the
-   `clients' is NULL, no such clients exist in the SILC Network. */
-typedef void (*SilcGetClientCallback)(SilcClient client,
-                                     SilcClientConnection conn,
-                                     SilcClientEntry *clients,
-                                     unsigned int clients_count,
-                                     void *context);
-
-/* Finds client entry or entries by the `nickname' and `server'. The 
-   completion callback will be called when the client entries has been found.
-
-   Note: this function is always asynchronous and resolves the client
-   information from the server. Thus, if you already know the client
-   information then use the silc_client_get_client_by_id function to
-   get the client entry since this function may be very slow and should
-   be used only to initially get the client entries. */
-void silc_client_get_clients(SilcClient client,
-                            SilcClientConnection conn,
-                            char *nickname,
-                            char *server,
-                            SilcGetClientCallback completion,
-                            void *context);
-
-/* Same as above function but does not resolve anything from the server.
-   This checks local cache and returns all clients from the cache. */
-SilcClientEntry *silc_client_get_clients_local(SilcClient client,
-                                              SilcClientConnection conn,
-                                              char *nickname,
-                                              char *server,
-                                              unsigned int *clients_count);
-
-/* Find entry for client by the client's ID. Returns the entry or NULL
-   if the entry was not found. */
-SilcClientEntry silc_client_get_client_by_id(SilcClient client,
-                                            SilcClientConnection conn,
-                                            SilcClientID *client_id);
-
-/* Finds entry for channel by the channel name. Returns the entry or NULL
-   if the entry was not found. It is found only if the client is joined
-   to the channel. */
-SilcChannelEntry silc_client_get_channel(SilcClient client,
+/* Key agreement callback that is called after the key agreement protocol
+   has been performed. This is called also if error occured during the
+   key agreement protocol. The `key' is the allocated key material and
+   the caller is responsible of freeing it. The `key' is NULL if error
+   has occured. The application can freely use the `key' to whatever
+   purpose it needs. See lib/silcske/silcske.h for the definition of
+   the SilcSKEKeyMaterial structure. */
+typedef void (*SilcKeyAgreementCallback)(SilcClient client,
                                         SilcClientConnection conn,
-                                        char *channel);
+                                        SilcClientEntry client_entry,
+                                        SilcSKEKeyMaterial *key,
+                                        void *context);
+
+/* Sends key agreement request to the remote client indicated by the
+   `client_entry'. If the caller provides the `hostname' and the `port'
+   arguments then the library will bind the client to that hostname and
+   that port for the key agreement protocol. It also sends the `hostname'
+   and the `port' in the key agreement packet to the remote client. This
+   would indicate that the remote client may initiate the key agreement
+   protocol to the `hostname' on the `port'.
+
+   If the `hostname' and `port' is not provided then empty key agreement
+   packet is sent to the remote client. The remote client may reply with
+   the same packet including its hostname and port. If the library receives
+   the reply from the remote client the `key_agreement' client operation
+   callback will be called to verify whether the user wants to perform the
+   key agreement or not. 
+
+   NOTE: If the application provided the `hostname' and the `port' and the 
+   remote side initiates the key agreement protocol it is not verified
+   from the user anymore whether the protocol should be executed or not.
+   By setting the `hostname' and `port' the user gives permission to
+   perform the protocol.
+
+   NOTE: If the remote side decides not to initiate the key agreement
+   or decides not to reply with the key agreement packet then we cannot
+   perform the key agreement at all. If the key agreement protocol is
+   performed the `completion' callback with `context' will be called.
+   If remote side decides to ignore the request the `completion' will never
+   be called and the caller is responsible of freeing the `context' memory. 
+   The application can do this by setting, for example, timeout. */
+void silc_client_send_key_agreement(SilcClient client,
+                                   SilcClientConnection conn,
+                                   SilcClientEntry client_entry,
+                                   char *hostname,
+                                   int port,
+                                   SilcKeyAgreementCallback completion,
+                                   void *context);
+
+/* This function can be called to unbind the hostname and the port for
+   the key agreement protocol. However, this function has effect only 
+   before the key agreement protocol has been performed. After it has
+   been performed the library will automatically unbind the port. The 
+   `client_entry' is the client to which we sent the key agreement 
+   request. */
+void silc_client_abort_key_agreement(SilcClient client,
+                                    SilcClientConnection conn,
+                                    SilcClientEntry client_entry);
 
 #endif