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;
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
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
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. */
/* 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
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
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,
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