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 silc_protocol_execute(protocol, client->timeout_queue, 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 silc_protocol_execute(protocol, client->timeout_queue, 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 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
351 /* Advance protocol state and call the next state if we are responder */
353 if (ctx->responder == TRUE)
354 silc_protocol_execute(protocol, client->timeout_queue, 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 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
389 /* Advance protocol state and call next state if we are initiator */
391 if (ctx->responder == FALSE)
392 silc_protocol_execute(protocol, client->timeout_queue, 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 silc_protocol_execute(protocol, client->timeout_queue, 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 silc_protocol_execute(protocol, client->timeout_queue, 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 silc_protocol_execute(protocol, client->timeout_queue, 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 silc_protocol_execute_final(protocol, client->timeout_queue);
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 silc_protocol_execute_final(protocol, client->timeout_queue);
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 silc_protocol_execute_final(protocol, client->timeout_queue);
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 silc_protocol_execute_final(protocol, client->timeout_queue);
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 silc_protocol_execute_final(protocol, client->timeout_queue);
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 silc_protocol_execute_final(protocol, client->timeout_queue);
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 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
954 ctx->ske = silc_ske_alloc();
955 ctx->ske->rng = client->rng;
956 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
957 silc_ske_get_group_by_number(conn->rekey->ske_group,
958 &ctx->ske->prop->group);
960 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
961 NULL, NULL, NULL, NULL);
962 if (status != SILC_SKE_STATUS_OK) {
963 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
966 protocol->state = SILC_PROTOCOL_STATE_ERROR;
967 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
971 /* Advance the protocol state */
973 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
976 * Do normal and simple re-key.
979 /* Send the REKEY_DONE to indicate we will take new keys into use */
980 silc_client_packet_send(client, ctx->sock,
981 SILC_PACKET_REKEY_DONE,
982 NULL, 0, NULL, NULL, NULL, 0, FALSE);
984 /* After we send REKEY_DONE we must set the sending encryption
985 key to the new key since all packets after this packet must
986 encrypted with the new key. */
987 silc_client_protocol_rekey_generate(client, ctx, TRUE);
989 /* The protocol ends in next stage. */
990 protocol->state = SILC_PROTOCOL_STATE_END;
995 * We are the initiator of this protocol
998 /* Start the re-key by sending the REKEY packet */
999 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
1000 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1002 if (ctx->pfs == TRUE) {
1004 * Use Perfect Forward Secrecy, ie. negotiate the key material
1005 * using the SKE protocol.
1007 ctx->ske = silc_ske_alloc();
1008 ctx->ske->rng = client->rng;
1009 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
1010 silc_ske_get_group_by_number(conn->rekey->ske_group,
1011 &ctx->ske->prop->group);
1014 silc_ske_initiator_phase_2(ctx->ske, NULL, NULL,
1015 silc_client_protocol_rekey_send_packet,
1018 if (status != SILC_SKE_STATUS_OK) {
1019 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1022 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1023 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1027 /* Advance the protocol state */
1031 * Do normal and simple re-key.
1034 /* Send the REKEY_DONE to indicate we will take new keys into use
1036 silc_client_packet_send(client, ctx->sock,
1037 SILC_PACKET_REKEY_DONE,
1038 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1040 /* After we send REKEY_DONE we must set the sending encryption
1041 key to the new key since all packets after this packet must
1042 encrypted with the new key. */
1043 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1045 /* The protocol ends in next stage. */
1046 protocol->state = SILC_PROTOCOL_STATE_END;
1054 * Second state, used only when oding re-key with PFS.
1056 if (ctx->responder == TRUE) {
1057 if (ctx->pfs == TRUE) {
1059 * Send our KE packe to the initiator now that we've processed
1060 * the initiator's KE packet.
1063 silc_ske_responder_finish(ctx->ske, NULL, NULL,
1064 SILC_SKE_PK_TYPE_SILC,
1065 silc_client_protocol_rekey_send_packet,
1068 if (status != SILC_SKE_STATUS_OK) {
1069 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1072 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1073 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1079 if (ctx->pfs == TRUE) {
1081 * The packet type must be KE packet
1083 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1084 /* Error in protocol */
1085 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1086 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1089 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
1090 NULL, NULL, NULL, NULL);
1091 if (status != SILC_SKE_STATUS_OK) {
1092 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1095 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1096 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1102 /* Send the REKEY_DONE to indicate we will take new keys into use
1104 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1105 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1107 /* After we send REKEY_DONE we must set the sending encryption
1108 key to the new key since all packets after this packet must
1109 encrypted with the new key. */
1110 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1112 /* The protocol ends in next stage. */
1113 protocol->state = SILC_PROTOCOL_STATE_END;
1116 case SILC_PROTOCOL_STATE_END:
1121 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1122 /* Error in protocol */
1123 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1124 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
1127 /* We received the REKEY_DONE packet and all packets after this is
1128 encrypted with the new key so set the decryption key to the new key */
1129 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1131 /* Protocol has ended, call the final callback */
1132 if (protocol->final_callback)
1133 silc_protocol_execute_final(protocol, client->timeout_queue);
1135 silc_protocol_free(protocol);
1138 case SILC_PROTOCOL_STATE_ERROR:
1143 if (ctx->pfs == TRUE) {
1144 /* Send abort notification */
1145 silc_ske_abort(ctx->ske, ctx->ske->status,
1146 silc_client_protocol_ke_send_packet,
1150 /* On error the final callback is always called. */
1151 if (protocol->final_callback)
1152 silc_protocol_execute_final(protocol, client->timeout_queue);
1154 silc_protocol_free(protocol);
1157 case SILC_PROTOCOL_STATE_FAILURE:
1159 * We have received failure from remote
1162 /* On error the final callback is always called. */
1163 if (protocol->final_callback)
1164 silc_protocol_execute_final(protocol, client->timeout_queue);
1166 silc_protocol_free(protocol);
1169 case SILC_PROTOCOL_STATE_UNKNOWN:
1175 /* Registers protocols used in client */
1177 void silc_client_protocols_register(void)
1179 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1180 silc_client_protocol_connection_auth);
1181 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1182 silc_client_protocol_key_exchange);
1183 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1184 silc_client_protocol_rekey);
1187 /* Unregisters protocols */
1189 void silc_client_protocols_unregister(void)
1191 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1192 silc_client_protocol_connection_auth);
1193 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1194 silc_client_protocol_key_exchange);
1195 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1196 silc_client_protocol_rekey);