5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 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 * Client side of the protocols.
25 #include "clientlibincludes.h"
26 #include "client_internal.h"
28 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
29 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
30 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
32 extern char *silc_version_string;
35 * Key Exhange protocol functions
38 /* Function that is called when SKE protocol sends packets to network. */
40 void silc_client_protocol_ke_send_packet(SilcSKE ske,
45 SilcProtocol protocol = (SilcProtocol)context;
46 SilcClientKEInternalContext *ctx =
47 (SilcClientKEInternalContext *)protocol->context;
48 SilcClient client = (SilcClient)ctx->client;
50 /* Send the packet immediately */
51 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
52 packet->data, packet->len, TRUE);
55 /* Public key verification callback. Called by the application. */
59 SilcSKEVerifyCbCompletion completion;
60 void *completion_context;
63 static void silc_client_verify_key_cb(bool success, void *context)
65 VerifyKeyContext verify = (VerifyKeyContext)context;
67 SILC_LOG_DEBUG(("Start"));
69 /* Call the completion callback back to the SKE */
70 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
71 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
72 verify->completion_context);
77 /* Callback that is called when we have received KE2 payload from
78 responder. We try to verify the public key now. */
80 void silc_client_protocol_ke_verify_key(SilcSKE ske,
81 unsigned char *pk_data,
83 SilcSKEPKType pk_type,
85 SilcSKEVerifyCbCompletion completion,
86 void *completion_context)
88 SilcProtocol protocol = (SilcProtocol)context;
89 SilcClientKEInternalContext *ctx =
90 (SilcClientKEInternalContext *)protocol->context;
91 SilcClient client = (SilcClient)ctx->client;
92 VerifyKeyContext verify;
94 SILC_LOG_DEBUG(("Start"));
96 verify = silc_calloc(1, sizeof(*verify));
98 verify->completion = completion;
99 verify->completion_context = completion_context;
101 /* Verify public key from user. */
102 client->ops->verify_public_key(client, ctx->sock->user_data,
104 pk_data, pk_len, pk_type,
105 silc_client_verify_key_cb, verify);
108 /* Sets the negotiated key material into use for particular connection. */
110 void silc_client_protocol_ke_set_keys(SilcSKE ske,
111 SilcSocketConnection sock,
112 SilcSKEKeyMaterial *keymat,
117 SilcSKEDiffieHellmanGroup group)
119 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
121 SILC_LOG_DEBUG(("Setting new keys into use"));
123 /* Allocate cipher to be used in the communication */
124 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
125 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
127 conn->send_key->cipher->set_key(conn->send_key->context,
128 keymat->send_enc_key,
129 keymat->enc_key_len);
130 conn->send_key->set_iv(conn->send_key, keymat->send_iv);
131 conn->receive_key->cipher->set_key(conn->receive_key->context,
132 keymat->receive_enc_key,
133 keymat->enc_key_len);
134 conn->receive_key->set_iv(conn->receive_key, keymat->receive_iv);
136 /* Allocate PKCS to be used */
138 /* XXX Do we ever need to allocate PKCS for the connection??
139 If yes, we need to change KE protocol to get the initiators
141 silc_pkcs_alloc(pkcs->pkcs->name, &conn->public_Key);
142 silc_pkcs_set_public_key(conn->public_key, ske->ke2_payload->pk_data,
143 ske->ke2_payload->pk_len);
146 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
147 conn->rekey->send_enc_key =
148 silc_calloc(keymat->enc_key_len / 8,
149 sizeof(*conn->rekey->send_enc_key));
150 memcpy(conn->rekey->send_enc_key,
151 keymat->send_enc_key, keymat->enc_key_len / 8);
152 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
154 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
155 conn->rekey->pfs = TRUE;
156 conn->rekey->ske_group = silc_ske_group_get_number(group);
158 /* Save HMAC key to be used in the communication. */
159 silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac_send);
160 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, keymat->hmac_key_len);
161 conn->hmac_receive = conn->hmac_send;
163 /* Save the HASH function */
164 silc_hash_alloc(hash->hash->name, &conn->hash);
167 /* Checks the version string of the server. */
169 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
172 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
173 SilcClient client = (SilcClient)ske->user_data;
174 SilcSKEStatus status = SILC_SKE_STATUS_OK;
176 int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
178 /* Check for initial version string */
179 if (!strstr(version, "SILC-1.0-"))
180 status = SILC_SKE_STATUS_BAD_VERSION;
182 /* Check software version */
186 status = SILC_SKE_STATUS_BAD_VERSION;
189 cp = strchr(cp, '.');
194 cp = strchr(cp, '.');
196 build = atoi(cp + 1);
198 cp = silc_version_string + 9;
200 status = SILC_SKE_STATUS_BAD_VERSION;
203 cp = strchr(cp, '.');
208 cp = strchr(cp, '.');
210 build2 = atoi(cp + 1);
213 status = SILC_SKE_STATUS_BAD_VERSION;
215 status = SILC_SKE_STATUS_BAD_VERSION;
217 if (status != SILC_SKE_STATUS_OK)
218 client->ops->say(client, conn,
219 "We don't support server version `%s'", version);
224 /* Callback that is called by the SKE to indicate that it is safe to
225 continue the execution of the protocol. Is given as argument to the
226 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
227 This is called due to the fact that the public key verification
228 process is asynchronous and we must not continue the protocl until
229 the public key has been verified and this callback is called. */
231 static void silc_client_protocol_ke_continue(SilcSKE ske,
234 SilcProtocol protocol = (SilcProtocol)context;
235 SilcClientKEInternalContext *ctx =
236 (SilcClientKEInternalContext *)protocol->context;
237 SilcClient client = (SilcClient)ctx->client;
238 SilcClientConnection conn = ctx->sock->user_data;
240 SILC_LOG_DEBUG(("Start"));
242 if (ske->status != SILC_SKE_STATUS_OK) {
243 if (ske->status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
244 client->ops->say(client, conn,
245 "Received unsupported server %s public key",
246 ctx->sock->hostname);
247 } else if (ske->status == SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED) {
248 client->ops->say(client, conn,
249 "Remote host did not send its public key, even though "
252 client->ops->say(client, conn,
253 "Error during key exchange protocol with server %s",
254 ctx->sock->hostname);
257 protocol->state = SILC_PROTOCOL_STATE_ERROR;
258 protocol->execute(client->timeout_queue, 0, protocol, 0, 0, 0);
262 /* Send Ok to the other end. We will end the protocol as server
263 sends Ok to us when we will take the new keys into use. Do this
264 if we are initiator. This is happens when this callback was sent
265 to silc_ske_initiator_finish function. */
266 if (ctx->responder == FALSE) {
267 silc_ske_end(ctx->ske, ctx->send_packet, context);
269 /* End the protocol on the next round */
270 protocol->state = SILC_PROTOCOL_STATE_END;
273 /* Advance protocol state and call the next state if we are responder.
274 This happens when this callback was sent to silc_ske_responder_phase_2
276 if (ctx->responder == TRUE) {
278 protocol->execute(client->timeout_queue, 0, protocol, 0, 0, 100000);
282 /* Performs key exchange protocol. This is used for both initiator
283 and responder key exchange. This may be called recursively. */
285 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
287 SilcProtocol protocol = (SilcProtocol)context;
288 SilcClientKEInternalContext *ctx =
289 (SilcClientKEInternalContext *)protocol->context;
290 SilcClient client = (SilcClient)ctx->client;
291 SilcClientConnection conn = ctx->sock->user_data;
292 SilcSKEStatus status = SILC_SKE_STATUS_OK;
294 SILC_LOG_DEBUG(("Start"));
296 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
297 protocol->state = SILC_PROTOCOL_STATE_START;
299 switch(protocol->state) {
300 case SILC_PROTOCOL_STATE_START:
307 /* Allocate Key Exchange object */
308 ske = silc_ske_alloc();
310 ske->rng = client->rng;
311 ske->user_data = (void *)client;
313 if (ctx->responder == TRUE) {
314 /* Start the key exchange by processing the received security
315 properties packet from initiator. */
316 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
318 ctx->packet->buffer, TRUE,
321 SilcSKEStartPayload *start_payload;
323 /* Assemble security properties. */
324 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
328 /* Start the key exchange by sending our security properties
329 to the remote end. */
330 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
336 /* Return now if the procedure is pending */
337 if (status == SILC_SKE_STATUS_PENDING)
340 if (status != SILC_SKE_STATUS_OK) {
341 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
343 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
346 protocol->state = SILC_PROTOCOL_STATE_ERROR;
347 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
351 /* Advance protocol state and call the next state if we are responder */
353 if (ctx->responder == TRUE)
354 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
362 if (ctx->responder == TRUE) {
363 /* Sends the selected security properties to the initiator. */
365 silc_ske_responder_phase_1(ctx->ske,
366 ctx->ske->start_payload,
370 /* Call Phase-1 function. This processes the Key Exchange Start
371 paylaod reply we just got from the responder. The callback
372 function will receive the processed payload where we will
374 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer,
378 if (status != SILC_SKE_STATUS_OK) {
379 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
381 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
384 protocol->state = SILC_PROTOCOL_STATE_ERROR;
385 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
389 /* Advance protocol state and call next state if we are initiator */
391 if (ctx->responder == FALSE)
392 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
400 if (ctx->responder == TRUE) {
401 /* Process the received Key Exchange 1 Payload packet from
402 the initiator. This also creates our parts of the Diffie
403 Hellman algorithm. The silc_client_protocol_ke_continue will
404 be called after the public key has been verified. */
405 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
406 ctx->verify, context,
407 silc_client_protocol_ke_continue,
410 /* Call the Phase-2 function. This creates Diffie Hellman
411 key exchange parameters and sends our public part inside
412 Key Exhange 1 Payload to the responder. */
413 status = silc_ske_initiator_phase_2(ctx->ske,
421 /* Return now if the procedure is pending */
422 if (status == SILC_SKE_STATUS_PENDING)
425 if (status != SILC_SKE_STATUS_OK) {
426 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
428 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
431 protocol->state = SILC_PROTOCOL_STATE_ERROR;
432 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
442 if (ctx->responder == TRUE) {
443 /* This creates the key exchange material and sends our
444 public parts to the initiator inside Key Exchange 2 Payload. */
446 silc_ske_responder_finish(ctx->ske,
447 client->public_key, client->private_key,
448 SILC_SKE_PK_TYPE_SILC,
452 /* End the protocol on the next round */
453 protocol->state = SILC_PROTOCOL_STATE_END;
455 /* Finish the protocol. This verifies the Key Exchange 2 payload
456 sent by responder. The silc_client_protocol_ke_continue will
457 be called after the public key has been verified. */
458 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
459 ctx->verify, context,
460 silc_client_protocol_ke_continue,
464 /* Return now if the procedure is pending */
465 if (status == SILC_SKE_STATUS_PENDING)
468 if (status != SILC_SKE_STATUS_OK) {
469 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
470 client->ops->say(client, conn,
471 "Received unsupported server %s public key",
472 ctx->sock->hostname);
474 client->ops->say(client, conn,
475 "Error during key exchange protocol with server %s",
476 ctx->sock->hostname);
478 protocol->state = SILC_PROTOCOL_STATE_ERROR;
479 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
485 case SILC_PROTOCOL_STATE_END:
490 SilcSKEKeyMaterial *keymat;
491 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
492 int hash_len = ctx->ske->prop->hash->hash->hash_len;
494 /* Process the key material */
495 keymat = silc_calloc(1, sizeof(*keymat));
496 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
498 if (status != SILC_SKE_STATUS_OK) {
499 protocol->state = SILC_PROTOCOL_STATE_ERROR;
500 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 300000);
501 silc_ske_free_key_material(keymat);
504 ctx->keymat = keymat;
506 /* Send Ok to the other end if we are responder. If we are initiator
507 we have sent this already. */
508 if (ctx->responder == TRUE)
509 silc_ske_end(ctx->ske, ctx->send_packet, context);
511 /* Unregister the timeout task since the protocol has ended.
512 This was the timeout task to be executed if the protocol is
513 not completed fast enough. */
514 if (ctx->timeout_task)
515 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
517 /* Protocol has ended, call the final callback */
518 if (protocol->final_callback)
519 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
521 silc_protocol_free(protocol);
525 case SILC_PROTOCOL_STATE_ERROR:
527 * Error during protocol
530 /* Send abort notification */
531 silc_ske_abort(ctx->ske, ctx->ske->status,
532 ctx->send_packet, context);
534 /* On error the final callback is always called. */
535 if (protocol->final_callback)
536 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
538 silc_protocol_free(protocol);
541 case SILC_PROTOCOL_STATE_FAILURE:
543 * Received failure from remote.
546 /* Unregister the timeout task since the protocol has ended.
547 This was the timeout task to be executed if the protocol is
548 not completed fast enough. */
549 if (ctx->timeout_task)
550 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
552 /* On error the final callback is always called. */
553 if (protocol->final_callback)
554 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
556 silc_protocol_free(protocol);
558 case SILC_PROTOCOL_STATE_UNKNOWN:
564 * Connection Authentication protocol functions
568 silc_client_get_public_key_auth(SilcClient client,
570 unsigned char *auth_data,
571 uint32 *auth_data_len,
577 SilcPublicKey pub_key;
579 if (!silc_pkcs_load_public_key(filepath,&pub_key, SILC_PKCS_FILE_PEM))
580 if (!silc_pkcs_load_public_key(filepath, &pub_key, SILC_PKCS_FILE_BIN))
583 silc_pkcs_alloc(pub_key->name, &pkcs);
584 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
585 silc_pkcs_free(pkcs);
586 silc_pkcs_public_key_free(pub_key);
590 /* Make the authentication data. Protocol says it is HASH plus
592 len = ske->hash_len + ske->start_payload_copy->len;
593 auth = silc_buffer_alloc(len);
594 silc_buffer_pull_tail(auth, len);
595 silc_buffer_format(auth,
596 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
597 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
598 ske->start_payload_copy->len),
601 if (silc_pkcs_sign(pkcs, auth->data, auth->len, auth_data, auth_data_len)) {
602 silc_pkcs_free(pkcs);
603 silc_buffer_free(auth);
604 silc_pkcs_public_key_free(pub_key);
608 silc_pkcs_free(pkcs);
609 silc_buffer_free(auth);
610 silc_pkcs_public_key_free(pub_key);
614 /* Continues the connection authentication protocol. This funtion may
615 be called directly or used as SilcAskPassphrase callback. */
618 silc_client_conn_auth_continue(unsigned char *auth_data,
619 uint32 auth_data_len, void *context)
621 SilcProtocol protocol = (SilcProtocol)context;
622 SilcClientConnAuthInternalContext *ctx =
623 (SilcClientConnAuthInternalContext *)protocol->context;
624 SilcClient client = (SilcClient)ctx->client;
628 SILC_LOG_DEBUG(("Start"));
630 payload_len = 4 + auth_data_len;
631 packet = silc_buffer_alloc(payload_len);
632 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
633 silc_buffer_format(packet,
634 SILC_STR_UI_SHORT(payload_len),
635 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
636 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
639 /* Send the packet to server */
640 silc_client_packet_send(client, ctx->sock,
641 SILC_PACKET_CONNECTION_AUTH,
643 packet->data, packet->len, TRUE);
646 memset(auth_data, 0, auth_data_len);
647 silc_free(auth_data);
649 silc_buffer_free(packet);
651 /* Next state is end of protocol */
652 protocol->state = SILC_PROTOCOL_STATE_END;
655 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
657 SilcProtocol protocol = (SilcProtocol)context;
658 SilcClientConnAuthInternalContext *ctx =
659 (SilcClientConnAuthInternalContext *)protocol->context;
660 SilcClient client = (SilcClient)ctx->client;
661 SilcClientConnection conn = ctx->sock->user_data;
663 SILC_LOG_DEBUG(("Start"));
665 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
666 protocol->state = SILC_PROTOCOL_STATE_START;
668 switch(protocol->state) {
669 case SILC_PROTOCOL_STATE_START:
672 * Start protocol. We send authentication data to the server
673 * to be authenticated.
675 unsigned char *auth_data = NULL;
676 uint32 auth_data_len = 0;
678 switch(ctx->auth_meth) {
680 /* No authentication required */
683 case SILC_AUTH_PASSWORD:
684 /* Password authentication */
685 if (ctx->auth_data && ctx->auth_data_len) {
686 auth_data = ctx->auth_data;
687 auth_data_len = ctx->auth_data_len;
691 client->ops->say(client, conn,
692 "Password authentication required by server %s",
693 ctx->sock->hostname);
694 client->ops->ask_passphrase(client, conn,
695 silc_client_conn_auth_continue,
700 case SILC_AUTH_PUBLIC_KEY:
702 unsigned char sign[1024];
704 /* Public key authentication */
705 silc_client_get_public_key_auth(client, ctx->auth_data,
706 sign, &auth_data_len,
708 auth_data = silc_calloc(auth_data_len, sizeof(*auth_data));
709 memcpy(auth_data, sign, auth_data_len);
714 silc_client_conn_auth_continue(auth_data,
715 auth_data_len, protocol);
719 case SILC_PROTOCOL_STATE_END:
722 * End protocol. Nothing special to be done here.
725 /* Protocol has ended, call the final callback */
726 if (protocol->final_callback)
727 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
729 silc_protocol_free(protocol);
733 case SILC_PROTOCOL_STATE_ERROR:
736 * Error. Send notify to remote.
738 unsigned char error[4];
740 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
742 /* Error in protocol. Send FAILURE packet. Although I don't think
743 this could ever happen on client side. */
744 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
745 NULL, 0, NULL, NULL, error, 4, TRUE);
747 /* On error the final callback is always called. */
748 if (protocol->final_callback)
749 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
751 silc_protocol_free(protocol);
754 case SILC_PROTOCOL_STATE_FAILURE:
756 * Received failure from remote.
759 /* On error the final callback is always called. */
760 if (protocol->final_callback)
761 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
763 silc_protocol_free(protocol);
766 case SILC_PROTOCOL_STATE_UNKNOWN:
772 * Re-key protocol routines
775 /* Actually takes the new keys into use. */
778 silc_client_protocol_rekey_validate(SilcClient client,
779 SilcClientRekeyInternalContext *ctx,
780 SilcSocketConnection sock,
781 SilcSKEKeyMaterial *keymat,
784 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
786 if (ctx->responder == TRUE) {
788 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
789 keymat->enc_key_len);
790 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
792 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
793 keymat->enc_key_len);
794 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
798 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
799 keymat->enc_key_len);
800 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
802 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
803 keymat->enc_key_len);
804 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
809 silc_hmac_alloc(conn->hmac_receive->hmac->name, NULL, &conn->hmac_send);
810 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key,
811 keymat->hmac_key_len);
813 silc_hmac_free(conn->hmac_receive);
814 conn->hmac_receive = conn->hmac_send;
817 /* Save the current sending encryption key */
819 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
820 silc_free(conn->rekey->send_enc_key);
821 conn->rekey->send_enc_key =
822 silc_calloc(keymat->enc_key_len / 8,
823 sizeof(*conn->rekey->send_enc_key));
824 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
825 keymat->enc_key_len / 8);
826 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
830 /* This function actually re-generates (when not using PFS) the keys and
831 takes them into use. */
834 silc_client_protocol_rekey_generate(SilcClient client,
835 SilcClientRekeyInternalContext *ctx,
838 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
839 SilcSKEKeyMaterial *keymat;
840 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
841 uint32 hash_len = conn->hash->hash->hash_len;
843 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
844 send ? "sending" : "receiving"));
846 /* Generate the new key */
847 keymat = silc_calloc(1, sizeof(*keymat));
848 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
849 conn->rekey->enc_key_len,
850 16, key_len, hash_len,
853 /* Set the keys into use */
854 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
856 silc_ske_free_key_material(keymat);
859 /* This function actually re-generates (with PFS) the keys and
860 takes them into use. */
863 silc_client_protocol_rekey_generate_pfs(SilcClient client,
864 SilcClientRekeyInternalContext *ctx,
867 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
868 SilcSKEKeyMaterial *keymat;
869 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
870 uint32 hash_len = conn->hash->hash->hash_len;
871 unsigned char *tmpbuf;
874 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
875 send ? "sending" : "receiving"));
877 /* Encode KEY to binary data */
878 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
880 /* Generate the new key */
881 keymat = silc_calloc(1, sizeof(*keymat));
882 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
885 /* Set the keys into use */
886 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
888 memset(tmpbuf, 0, klen);
890 silc_ske_free_key_material(keymat);
893 /* Packet sending callback. This function is provided as packet sending
894 routine to the Key Exchange functions. */
897 silc_client_protocol_rekey_send_packet(SilcSKE ske,
902 SilcProtocol protocol = (SilcProtocol)context;
903 SilcClientRekeyInternalContext *ctx =
904 (SilcClientRekeyInternalContext *)protocol->context;
905 SilcClient client = (SilcClient)ctx->client;
907 /* Send the packet immediately */
908 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
909 packet->data, packet->len, FALSE);
912 /* Performs re-key as defined in the SILC protocol specification. */
914 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
916 SilcProtocol protocol = (SilcProtocol)context;
917 SilcClientRekeyInternalContext *ctx =
918 (SilcClientRekeyInternalContext *)protocol->context;
919 SilcClient client = (SilcClient)ctx->client;
920 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
921 SilcSKEStatus status;
923 SILC_LOG_DEBUG(("Start"));
925 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
926 protocol->state = SILC_PROTOCOL_STATE_START;
928 SILC_LOG_DEBUG(("State=%d", protocol->state));
930 switch(protocol->state) {
931 case SILC_PROTOCOL_STATE_START:
937 if (ctx->responder == TRUE) {
939 * We are receiving party
942 if (ctx->pfs == TRUE) {
944 * Use Perfect Forward Secrecy, ie. negotiate the key material
945 * using the SKE protocol.
948 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
949 /* Error in protocol */
950 protocol->state = SILC_PROTOCOL_STATE_ERROR;
951 protocol->execute(client->timeout_queue, 0, protocol, fd,
955 ctx->ske = silc_ske_alloc();
956 ctx->ske->rng = client->rng;
957 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
958 silc_ske_get_group_by_number(conn->rekey->ske_group,
959 &ctx->ske->prop->group);
961 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
962 NULL, NULL, NULL, NULL);
963 if (status != SILC_SKE_STATUS_OK) {
964 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
967 protocol->state = SILC_PROTOCOL_STATE_ERROR;
968 protocol->execute(client->timeout_queue, 0,
969 protocol, fd, 0, 300000);
973 /* Advance the protocol state */
975 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
978 * Do normal and simple re-key.
981 /* Send the REKEY_DONE to indicate we will take new keys into use */
982 silc_client_packet_send(client, ctx->sock,
983 SILC_PACKET_REKEY_DONE,
984 NULL, 0, NULL, NULL, NULL, 0, FALSE);
986 /* After we send REKEY_DONE we must set the sending encryption
987 key to the new key since all packets after this packet must
988 encrypted with the new key. */
989 silc_client_protocol_rekey_generate(client, ctx, TRUE);
991 /* The protocol ends in next stage. */
992 protocol->state = SILC_PROTOCOL_STATE_END;
997 * We are the initiator of this protocol
1000 /* Start the re-key by sending the REKEY packet */
1001 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
1002 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1004 if (ctx->pfs == TRUE) {
1006 * Use Perfect Forward Secrecy, ie. negotiate the key material
1007 * using the SKE protocol.
1009 ctx->ske = silc_ske_alloc();
1010 ctx->ske->rng = client->rng;
1011 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
1012 silc_ske_get_group_by_number(conn->rekey->ske_group,
1013 &ctx->ske->prop->group);
1016 silc_ske_initiator_phase_2(ctx->ske, NULL, NULL,
1017 silc_client_protocol_rekey_send_packet,
1020 if (status != SILC_SKE_STATUS_OK) {
1021 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1024 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1025 protocol->execute(client->timeout_queue, 0,
1026 protocol, fd, 0, 300000);
1030 /* Advance the protocol state */
1034 * Do normal and simple re-key.
1037 /* Send the REKEY_DONE to indicate we will take new keys into use
1039 silc_client_packet_send(client, ctx->sock,
1040 SILC_PACKET_REKEY_DONE,
1041 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1043 /* After we send REKEY_DONE we must set the sending encryption
1044 key to the new key since all packets after this packet must
1045 encrypted with the new key. */
1046 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1048 /* The protocol ends in next stage. */
1049 protocol->state = SILC_PROTOCOL_STATE_END;
1057 * Second state, used only when oding re-key with PFS.
1059 if (ctx->responder == TRUE) {
1060 if (ctx->pfs == TRUE) {
1062 * Send our KE packe to the initiator now that we've processed
1063 * the initiator's KE packet.
1066 silc_ske_responder_finish(ctx->ske, NULL, NULL,
1067 SILC_SKE_PK_TYPE_SILC,
1068 silc_client_protocol_rekey_send_packet,
1071 if (status != SILC_SKE_STATUS_OK) {
1072 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1075 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1076 protocol->execute(client->timeout_queue, 0,
1077 protocol, fd, 0, 300000);
1083 if (ctx->pfs == TRUE) {
1085 * The packet type must be KE packet
1087 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1088 /* Error in protocol */
1089 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1090 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 300000);
1093 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
1094 NULL, NULL, NULL, NULL);
1095 if (status != SILC_SKE_STATUS_OK) {
1096 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1099 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1100 protocol->execute(client->timeout_queue, 0,
1101 protocol, fd, 0, 300000);
1107 /* Send the REKEY_DONE to indicate we will take new keys into use
1109 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1110 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1112 /* After we send REKEY_DONE we must set the sending encryption
1113 key to the new key since all packets after this packet must
1114 encrypted with the new key. */
1115 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1117 /* The protocol ends in next stage. */
1118 protocol->state = SILC_PROTOCOL_STATE_END;
1121 case SILC_PROTOCOL_STATE_END:
1126 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1127 /* Error in protocol */
1128 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1129 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
1132 /* We received the REKEY_DONE packet and all packets after this is
1133 encrypted with the new key so set the decryption key to the new key */
1134 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1136 /* Protocol has ended, call the final callback */
1137 if (protocol->final_callback)
1138 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
1140 silc_protocol_free(protocol);
1143 case SILC_PROTOCOL_STATE_ERROR:
1148 if (ctx->pfs == TRUE) {
1149 /* Send abort notification */
1150 silc_ske_abort(ctx->ske, ctx->ske->status,
1151 silc_client_protocol_ke_send_packet,
1155 /* On error the final callback is always called. */
1156 if (protocol->final_callback)
1157 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
1159 silc_protocol_free(protocol);
1162 case SILC_PROTOCOL_STATE_FAILURE:
1164 * We have received failure from remote
1167 /* On error the final callback is always called. */
1168 if (protocol->final_callback)
1169 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
1171 silc_protocol_free(protocol);
1174 case SILC_PROTOCOL_STATE_UNKNOWN:
1180 /* Registers protocols used in client */
1182 void silc_client_protocols_register(void)
1184 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1185 silc_client_protocol_connection_auth);
1186 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1187 silc_client_protocol_key_exchange);
1188 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1189 silc_client_protocol_rekey);
1192 /* Unregisters protocols */
1194 void silc_client_protocols_unregister(void)
1196 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1197 silc_client_protocol_connection_auth);
1198 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1199 silc_client_protocol_key_exchange);
1200 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1201 silc_client_protocol_rekey);