5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 /* This file includes the Key Agreement packet processing and actual
22 key agreement routines. This file has nothing to do with the actual
23 connection key exchange protocol, it is implemented in the client.c
24 and in protocol.c. This file implements the client-to-client key
25 agreement as defined by the SILC protocol. */
27 #include "silcincludes.h"
28 #include "silcclient.h"
29 #include "client_internal.h"
31 SILC_TASK_CALLBACK(silc_client_key_agreement_final);
32 SILC_TASK_CALLBACK(silc_client_process_key_agreement);
33 SILC_TASK_CALLBACK(silc_client_key_agreement_timeout);
34 SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start);
36 /* Key agreement context */
37 struct SilcClientKeyAgreementStruct {
39 SilcClientConnection conn;
40 int fd; /* Listening/connection socket */
41 SilcSocketConnection sock; /* Remote socket connection */
42 SilcClientEntry client_entry; /* Destination client */
43 SilcKeyAgreementCallback completion; /* Key agreement completion */
44 void *context; /* User context */
45 SilcTask timeout; /* Timeout task */
46 SilcClientKEInternalContext *proto_ctx; /* Key Exchange protocol context */
49 /* Packet sending function used by the SKE in the key agreement process. */
51 static void silc_client_key_agreement_send_packet(SilcSKE ske,
56 SilcProtocol protocol = (SilcProtocol)context;
57 SilcClientKEInternalContext *ctx =
58 (SilcClientKEInternalContext *)protocol->context;
61 /* Send the packet immediately. We will assure that the packet is not
62 encrypted by setting the socket's user_data pointer to NULL. The
63 silc_client_packet_send would take the keys (wrong keys that is,
64 because user_data is the current SilcClientConnection) from it and
65 we cannot allow that. The packets are never encrypted when doing SKE
66 with another client. */
67 tmp = ske->sock->user_data;
68 ske->sock->user_data = NULL;
69 silc_client_packet_send(ctx->client, ske->sock, type, NULL, 0, NULL, NULL,
70 packet->data, packet->len, TRUE);
71 ske->sock->user_data = tmp;
74 /* Timeout callback that is called to close the connection and free the
75 socket connection data. */
77 SILC_TASK_CALLBACK(silc_client_key_agreement_close)
79 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
81 silc_schedule_unset_listen_fd(ke->client->schedule, ke->sock->sock);
82 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
83 silc_net_close_connection(ke->sock->sock);
84 silc_net_close_connection(ke->fd);
85 silc_socket_free(ke->sock);
89 /* This callback is called after the key agreement protocol has been
90 performed. This calls the final completion callback for the application. */
92 SILC_TASK_CALLBACK(silc_client_key_agreement_final)
94 SilcProtocol protocol = (SilcProtocol)context;
95 SilcClientKEInternalContext *ctx =
96 (SilcClientKEInternalContext *)protocol->context;
97 SilcClient client = (SilcClient)ctx->client;
98 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)ctx->context;
100 SILC_LOG_DEBUG(("Start"));
102 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
103 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
104 /* Error occured during protocol */
105 ke->client_entry->ke = NULL;
106 ke->completion(ke->client, ke->conn, ke->client_entry,
107 SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
108 silc_ske_free_key_material(ctx->keymat);
112 /* Pass the negotiated key material to the application. The application
113 is responsible of freeing the key material. */
114 ke->client_entry->ke = NULL;
115 ke->completion(ke->client, ke->conn, ke->client_entry,
116 SILC_KEY_AGREEMENT_OK, ctx->keymat, ke->context);
119 silc_protocol_free(protocol);
121 silc_ske_free(ctx->ske);
123 silc_free(ctx->dest_id);
124 silc_schedule_task_del_by_fd(client->schedule, ke->fd);
125 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
126 silc_net_close_connection(ke->fd);
128 silc_schedule_task_del(client->schedule, ke->timeout);
129 silc_client_del_socket(ke->client, ke->sock);
131 silc_schedule_task_add(client->schedule, 0,
132 silc_client_key_agreement_close,
134 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
139 /* Key agreement callback that is called when remote end has initiated
140 the key agreement protocol. This accepts the incoming TCP/IP connection
141 for the key agreement protocol. */
143 SILC_TASK_CALLBACK(silc_client_process_key_agreement)
145 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
146 SilcClient client = ke->client;
147 SilcClientConnection conn = ke->conn;
148 SilcSocketConnection newsocket;
149 SilcClientKEInternalContext *proto_ctx;
152 SILC_LOG_DEBUG(("Start"));
154 sock = silc_net_accept_connection(ke->fd);
156 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
157 "Could not accept key agreement connection: ",
159 ke->client_entry->ke = NULL;
160 ke->completion(ke->client, ke->conn, ke->client_entry,
161 SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
162 silc_schedule_task_del_by_fd(client->schedule, ke->fd);
163 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
164 silc_net_close_connection(ke->fd);
166 silc_schedule_task_del(client->schedule, ke->timeout);
171 /* Set socket options */
172 silc_net_set_socket_nonblock(sock);
173 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
175 /* Create socket for this connection (it is of type UNKNOWN since this
176 really is not a real SILC connection. It is only for the key
177 agreement protocol). */
178 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, (void *)conn, &newsocket);
179 ke->sock = newsocket;
181 /* Perform name and address lookups for the remote host. */
182 silc_net_check_host_by_sock(sock, &newsocket->hostname, &newsocket->ip);
183 if (!newsocket->hostname && !newsocket->ip) {
184 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
185 "Could not resolve the remote IP or hostname");
186 ke->client_entry->ke = NULL;
187 ke->completion(ke->client, ke->conn, ke->client_entry,
188 SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
189 silc_schedule_task_del_by_fd(client->schedule, ke->fd);
190 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
191 silc_net_close_connection(ke->fd);
193 silc_schedule_task_del(client->schedule, ke->timeout);
197 if (!newsocket->hostname)
198 newsocket->hostname = strdup(newsocket->ip);
199 newsocket->port = silc_net_get_remote_port(sock);
200 silc_client_add_socket(client, newsocket);
202 /* Allocate internal context for key exchange protocol. This is
203 sent as context for the protocol. */
204 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
205 proto_ctx->client = client;
206 proto_ctx->sock = silc_socket_dup(newsocket);
207 proto_ctx->rng = client->rng;
208 proto_ctx->responder = TRUE;
209 proto_ctx->context = context;
210 proto_ctx->send_packet = silc_client_key_agreement_send_packet;
211 proto_ctx->verify = silc_client_protocol_ke_verify_key;
212 ke->proto_ctx = proto_ctx;
214 /* Prepare the connection for key exchange protocol. We allocate the
215 protocol but will not start it yet. The connector will be the
216 initiator of the protocol thus we will wait for initiation from
217 there before we start the protocol. */
218 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
219 &newsocket->protocol, proto_ctx,
220 silc_client_key_agreement_final);
222 /* Register the connection for network input and output. This sets
223 that scheduler will listen for incoming packets for this connection
224 and sets that outgoing packets may be sent to this connection as well.
225 However, this doesn't set the scheduler for outgoing traffic, it
226 will be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
227 later when outgoing data is available. */
228 context = (void *)client;
229 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
232 /* Timeout occured during key agreement. This means that the key agreement
233 protocol was not completed in the specified timeout. We will call the
234 completion callback. */
236 SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
238 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
240 ke->client_entry->ke = NULL;
241 ke->completion(ke->client, ke->conn, ke->client_entry,
242 SILC_KEY_AGREEMENT_TIMEOUT, NULL, ke->context);
245 silc_client_del_socket(ke->client, ke->sock);
246 silc_socket_free(ke->sock);
248 if (ke->proto_ctx && ke->proto_ctx->ske)
249 silc_ske_free(ke->proto_ctx->ske);
250 ke->client_entry->ke = NULL;
252 silc_schedule_task_del_by_fd(ke->client->schedule, ke->fd);
253 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
254 silc_net_close_connection(ke->fd);
258 /* Sends key agreement request to the remote client indicated by the
259 `client_entry'. If the caller provides the `hostname' and the `port'
260 arguments then the library will bind the client to that hostname and
261 that port for the key agreement protocol. It also sends the `hostname'
262 and the `port' in the key agreement packet to the remote client. This
263 would indicate that the remote client may initiate the key agreement
264 protocol to the `hostname' on the `port'. If port is zero then the
265 bound port is undefined (the operating system defines it).
267 If the `hostname' and `port' is not provided then empty key agreement
268 packet is sent to the remote client. The remote client may reply with
269 the same packet including its hostname and port. If the library receives
270 the reply from the remote client the `key_agreement' client operation
271 callback will be called to verify whether the user wants to perform the
272 key agreement or not.
274 NOTE: If the application provided the `hostname' and the `port' and the
275 remote side initiates the key agreement protocol it is not verified
276 from the user anymore whether the protocol should be executed or not.
277 By setting the `hostname' and `port' the user gives permission to
278 perform the protocol (we are responder in this case).
280 NOTE: If the remote side decides not to initiate the key agreement
281 or decides not to reply with the key agreement packet then we cannot
282 perform the key agreement at all. If the key agreement protocol is
283 performed the `completion' callback with the `context' will be called.
284 If remote side decides to ignore the request the `completion' will be
285 called after the specified timeout, `timeout_secs'.
287 NOTE: If the `hostname' and the `port' was not provided the `completion'
288 will not be called at all since this does nothing more than sending
289 a packet to the remote host.
291 NOTE: There can be only one active key agreement for one client entry.
292 Before setting new one, the old one must be finished (it is finished
293 after calling the completion callback) or the function
294 silc_client_abort_key_agreement must be called. */
296 void silc_client_send_key_agreement(SilcClient client,
297 SilcClientConnection conn,
298 SilcClientEntry client_entry,
299 const char *hostname,
300 const char *bindhost,
302 SilcUInt32 timeout_secs,
303 SilcKeyAgreementCallback completion,
306 SilcSocketConnection sock = conn->sock;
307 SilcClientKeyAgreement ke = NULL;
313 if (client_entry->ke) {
314 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_ALREADY_STARTED,
319 if (client_entry == conn->local_entry) {
320 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
325 /* Create the listener if hostname and port was provided.
326 * also, use bindhost if it was specified.
330 ke = silc_calloc(1, sizeof(*ke));
333 ke->fd = silc_net_create_server(port, bindhost);
335 ke->fd = silc_net_create_server(port, hostname);
338 client->internal->ops->say(
339 client, conn, SILC_CLIENT_MESSAGE_ERROR,
340 "Cannot create listener on %s on port %d: %s",
341 (bindhost) ? bindhost:hostname, port, strerror(errno));
342 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
350 ke->client_entry = client_entry;
351 ke->completion = completion;
352 ke->context = context;
354 /* Add listener task to the scheduler. This task receives the key
356 silc_schedule_task_add(client->schedule, ke->fd,
357 silc_client_process_key_agreement,
360 SILC_TASK_PRI_NORMAL);
362 /* Register a timeout task that will be executed if the connector
363 will not start the key exchange protocol within the specified
365 ke->timeout = silc_schedule_task_add(client->schedule, 0,
366 silc_client_key_agreement_timeout,
367 (void *)ke, timeout_secs, 0,
368 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
371 /* Encode the key agreement payload */
372 buffer = silc_key_agreement_payload_encode(hostname,
374 silc_net_get_local_port(ke->fd));
376 /* Send the key agreement packet to the client */
377 silc_client_packet_send(client, sock, SILC_PACKET_KEY_AGREEMENT,
378 client_entry->id, SILC_ID_CLIENT, NULL, NULL,
379 buffer->data, buffer->len, FALSE);
380 silc_buffer_free(buffer);
384 silc_client_connect_to_client_internal(SilcClientInternalConnectContext *ctx)
388 /* Create connection to server asynchronously */
389 sock = silc_net_create_connection_async(NULL, ctx->port, ctx->host);
393 /* Register task that will receive the async connect and will
395 ctx->task = silc_schedule_task_add(ctx->client->schedule, sock,
396 silc_client_perform_key_agreement_start,
399 SILC_TASK_PRI_NORMAL);
400 silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE,
408 /* Routine used by silc_client_perform_key_agreement to create connection
409 to the remote client on specified port. */
412 silc_client_connect_to_client(SilcClient client,
413 SilcClientConnection conn, int port,
414 char *host, void *context)
416 SilcClientInternalConnectContext *ctx;
418 /* Allocate internal context for connection process. This is
419 needed as we are doing async connecting. */
420 ctx = silc_calloc(1, sizeof(*ctx));
421 ctx->client = client;
423 ctx->host = strdup(host);
426 ctx->context = context;
428 /* Do the actual connecting process */
429 return silc_client_connect_to_client_internal(ctx);
432 /* Callback that is called after connection has been created. This actually
433 starts the key agreement protocol. This is initiator function. */
435 SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
437 SilcClientInternalConnectContext *ctx =
438 (SilcClientInternalConnectContext *)context;
439 SilcClient client = ctx->client;
440 SilcClientConnection conn = ctx->conn;
441 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)ctx->context;
442 int opt, opt_len = sizeof(opt);
444 SILC_LOG_DEBUG(("Start"));
446 /* Check the socket status as it might be in error */
447 silc_net_get_socket_opt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
449 if (ctx->tries < 2) {
450 /* Connection failed but lets try again */
451 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
452 "Could not connect to client %s: %s",
453 ctx->host, strerror(opt));
454 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
455 "Connecting to port %d of client %s resumed",
456 ctx->port, ctx->host);
458 /* Unregister old connection try */
459 silc_schedule_unset_listen_fd(client->schedule, fd);
460 silc_net_close_connection(fd);
461 silc_schedule_task_del(client->schedule, ctx->task);
464 silc_client_connect_to_client_internal(ctx);
467 /* Connection failed and we won't try anymore */
468 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
469 "Could not connect to client %s: %s",
470 ctx->host, strerror(opt));
471 silc_schedule_unset_listen_fd(client->schedule, fd);
472 silc_net_close_connection(fd);
473 silc_schedule_task_del(client->schedule, ctx->task);
474 silc_free(ctx->host);
477 /* Call the completion callback */
478 ke->completion(ke->client, ke->conn, ke->client_entry,
479 SILC_KEY_AGREEMENT_FAILURE, NULL, ke->context);
485 silc_schedule_unset_listen_fd(client->schedule, fd);
486 silc_schedule_task_del(client->schedule, ctx->task);
490 /* Now actually perform the key agreement protocol */
491 silc_client_perform_key_agreement_fd(ke->client, ke->conn,
492 ke->client_entry, ke->fd, ctx->host,
493 ke->completion, ke->context);
495 silc_free(ctx->host);
499 /* Performs the actual key agreement protocol. Application may use this
500 to initiate the key agreement protocol. This can be called for example
501 after the application has received the `key_agreement' client operation,
502 and did not return TRUE from it.
504 The `hostname' is the remote hostname (or IP address) and the `port'
505 is the remote port. The `completion' callback with the `context' will
506 be called after the key agreement protocol.
508 NOTE: If the application returns TRUE in the `key_agreement' client
509 operation the library will automatically start the key agreement. In this
510 case the application must not call this function. However, application
511 may choose to just ignore the `key_agreement' client operation (and
512 merely just print information about it on the screen) and call this
513 function when the user whishes to do so (by, for example, giving some
514 specific command). Thus, the API provides both, automatic and manual
515 initiation of the key agreement. Calling this function is the manual
516 initiation and returning TRUE in the `key_agreement' client operation
517 is the automatic initiation. */
519 void silc_client_perform_key_agreement(SilcClient client,
520 SilcClientConnection conn,
521 SilcClientEntry client_entry,
524 SilcKeyAgreementCallback completion,
527 SilcClientKeyAgreement ke;
529 SILC_LOG_DEBUG(("Start"));
534 if (!hostname || !port) {
535 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
540 if (client_entry == conn->local_entry) {
541 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
546 ke = silc_calloc(1, sizeof(*ke));
549 ke->client_entry = client_entry;
550 ke->completion = completion;
551 ke->context = context;
553 /* Connect to the remote client */
554 ke->fd = silc_client_connect_to_client(client, conn, port, hostname, ke);
556 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
563 /* Same as above but application has created already the connection to
564 the remote host. The `sock' is the socket to the remote connection.
565 Application can use this function if it does not want the client library
566 to create the connection. */
568 void silc_client_perform_key_agreement_fd(SilcClient client,
569 SilcClientConnection conn,
570 SilcClientEntry client_entry,
573 SilcKeyAgreementCallback completion,
576 SilcClientKeyAgreement ke;
577 SilcClientKEInternalContext *proto_ctx;
578 SilcProtocol protocol;
580 SILC_LOG_DEBUG(("Start"));
585 if (client_entry == conn->local_entry) {
586 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
591 ke = silc_calloc(1, sizeof(*ke));
594 ke->client_entry = client_entry;
596 ke->completion = completion;
597 ke->context = context;
599 /* Allocate new socket connection object */
600 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, (void *)conn, &ke->sock);
601 silc_client_add_socket(client, ke->sock);
602 ke->sock->hostname = strdup(hostname);
603 ke->sock->port = silc_net_get_remote_port(sock);
605 /* Allocate internal context for key exchange protocol. This is
606 sent as context for the protocol. */
607 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
608 proto_ctx->client = client;
609 proto_ctx->sock = silc_socket_dup(ke->sock);
610 proto_ctx->rng = client->rng;
611 proto_ctx->responder = FALSE;
612 proto_ctx->context = ke;
613 proto_ctx->send_packet = silc_client_key_agreement_send_packet;
614 proto_ctx->verify = silc_client_protocol_ke_verify_key;
615 ke->proto_ctx = proto_ctx;
617 /* Perform key exchange protocol. */
618 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
619 &protocol, (void *)proto_ctx,
620 silc_client_key_agreement_final);
621 ke->sock->protocol = protocol;
623 /* Register the connection for network input and output. This sets
624 that scheduler will listen for incoming packets for this connection
625 and sets that outgoing packets may be sent to this connection as well.
626 However, this doesn't set the scheduler for outgoing traffic, it will
627 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
628 later when outgoing data is available. */
629 context = (void *)client;
630 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
632 /* Execute the protocol */
633 silc_protocol_execute(protocol, client->schedule, 0, 0);
636 /* This function can be called to unbind the hostname and the port for
637 the key agreement protocol. However, this function has effect only
638 before the key agreement protocol has been performed. After it has
639 been performed the library will automatically unbind the port. The
640 `client_entry' is the client to which we sent the key agreement
643 void silc_client_abort_key_agreement(SilcClient client,
644 SilcClientConnection conn,
645 SilcClientEntry client_entry)
650 if (client_entry->ke) {
651 SilcClientKeyAgreement ke;
653 if (client_entry->ke->sock) {
654 silc_client_del_socket(client_entry->ke->client, client_entry->ke->sock);
655 silc_socket_free(client_entry->ke->sock);
657 silc_schedule_task_del_by_fd(client->schedule, client_entry->ke->fd);
658 if (client_entry->ke->timeout)
659 silc_schedule_task_del(client->schedule,
660 client_entry->ke->timeout);
661 ke = client_entry->ke;
662 client_entry->ke = NULL;
663 ke->completion(client, conn, client_entry,
664 SILC_KEY_AGREEMENT_ABORTED, NULL, ke->context);
669 /* Callback function that is called after we've resolved the client
670 information who sent us the key agreement packet from the server.
671 We actually call the key_agreement client operation now. */
674 silc_client_key_agreement_resolve_cb(SilcClient client,
675 SilcClientConnection conn,
676 SilcClientEntry *clients,
677 SilcUInt32 clients_count,
680 SilcPacketContext *packet = (SilcPacketContext *)context;
681 SilcKeyAgreementPayload payload;
683 SilcKeyAgreementCallback completion;
684 void *completion_context;
689 /* Parse the key agreement payload */
690 payload = silc_key_agreement_payload_parse(packet->buffer->data,
691 packet->buffer->len);
695 /* Call the key_agreement client operation */
696 ret = client->internal->ops->key_agreement(
697 client, conn, clients[0],
698 silc_key_agreement_get_hostname(payload),
699 silc_key_agreement_get_port(payload),
700 &completion, &completion_context);
702 /* If the user returned TRUE then we'll start the key agreement right
703 here and right now. */
705 silc_client_perform_key_agreement(client, conn, clients[0],
706 silc_key_agreement_get_hostname(payload),
707 silc_key_agreement_get_port(payload),
708 completion, completion_context);
710 silc_key_agreement_payload_free(payload);
713 silc_packet_context_free(packet);
716 /* Received Key Agreement packet from remote client. Process the packet
717 and resolve the client information from the server before actually
718 letting the application know that we've received this packet. Then
719 call the key_agreement client operation and let the user decide
720 whether we perform the key agreement protocol now or not. */
722 void silc_client_key_agreement(SilcClient client,
723 SilcSocketConnection sock,
724 SilcPacketContext *packet)
726 SilcClientID *remote_id;
728 if (packet->src_id_type != SILC_ID_CLIENT)
731 remote_id = silc_id_str2id(packet->src_id, packet->src_id_len,
736 silc_client_get_client_by_id_resolve(client, sock->user_data, remote_id,
738 silc_client_key_agreement_resolve_cb,
739 silc_packet_context_dup(packet));
740 silc_free(remote_id);