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 "silcincludes.h"
26 #include "silcclient.h"
27 #include "client_internal.h"
29 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
30 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
31 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
34 * Key Exhange protocol functions
37 /* Function that is called when SKE protocol sends packets to network. */
39 void silc_client_protocol_ke_send_packet(SilcSKE ske,
44 SilcProtocol protocol = (SilcProtocol)context;
45 SilcClientKEInternalContext *ctx =
46 (SilcClientKEInternalContext *)protocol->context;
47 SilcClient client = (SilcClient)ctx->client;
49 /* Send the packet immediately */
50 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
51 packet->data, packet->len, TRUE);
54 /* Public key verification callback. Called by the application. */
58 SilcSKEVerifyCbCompletion completion;
59 void *completion_context;
62 static void silc_client_verify_key_cb(bool success, void *context)
64 VerifyKeyContext verify = (VerifyKeyContext)context;
66 SILC_LOG_DEBUG(("Start"));
68 /* Call the completion callback back to the SKE */
69 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
70 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
71 verify->completion_context);
76 /* Callback that is called when we have received KE payload from
77 responder. We try to verify the public key now. */
79 void silc_client_protocol_ke_verify_key(SilcSKE ske,
80 unsigned char *pk_data,
82 SilcSKEPKType pk_type,
84 SilcSKEVerifyCbCompletion completion,
85 void *completion_context)
87 SilcProtocol protocol = (SilcProtocol)context;
88 SilcClientKEInternalContext *ctx =
89 (SilcClientKEInternalContext *)protocol->context;
90 SilcClient client = (SilcClient)ctx->client;
91 VerifyKeyContext verify;
93 SILC_LOG_DEBUG(("Start"));
95 verify = silc_calloc(1, sizeof(*verify));
97 verify->completion = completion;
98 verify->completion_context = completion_context;
100 /* Verify public key from user. */
101 client->internal->ops->verify_public_key(client, ctx->sock->user_data,
103 pk_data, pk_len, pk_type,
104 silc_client_verify_key_cb, verify);
107 /* Sets the negotiated key material into use for particular connection. */
109 void silc_client_protocol_ke_set_keys(SilcSKE ske,
110 SilcSocketConnection sock,
111 SilcSKEKeyMaterial *keymat,
116 SilcSKEDiffieHellmanGroup group,
119 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
120 const char *cname = silc_cipher_get_name(cipher);
122 SILC_LOG_DEBUG(("Setting new keys into use"));
124 /* Allocate cipher to be used in the communication */
125 silc_cipher_alloc((char *)cname, &conn->internal->send_key);
126 silc_cipher_alloc((char *)cname, &conn->internal->receive_key);
127 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
128 &conn->internal->hmac_send);
129 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
130 &conn->internal->hmac_receive);
132 if (is_responder == TRUE) {
133 silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
134 keymat->enc_key_len);
135 silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv);
136 silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
137 keymat->enc_key_len);
138 silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv);
139 silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
140 keymat->hmac_key_len);
141 silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
142 keymat->hmac_key_len);
144 silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
145 keymat->enc_key_len);
146 silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv);
147 silc_cipher_set_key(conn->internal->receive_key, keymat->receive_enc_key,
148 keymat->enc_key_len);
149 silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv);
150 silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
151 keymat->hmac_key_len);
152 silc_hmac_set_key(conn->internal->hmac_receive, keymat->receive_hmac_key,
153 keymat->hmac_key_len);
157 conn->internal->rekey = silc_calloc(1, sizeof(*conn->internal->rekey));
158 conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
159 keymat->enc_key_len / 8);
160 conn->internal->rekey->enc_key_len = keymat->enc_key_len / 8;
162 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
163 conn->internal->rekey->pfs = TRUE;
164 conn->internal->rekey->ske_group = silc_ske_group_get_number(group);
166 /* Save the HASH function */
167 silc_hash_alloc(silc_hash_get_name(hash), &conn->internal->hash);
170 /* Checks the version string of the server. */
172 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
173 SilcUInt32 len, void *context)
175 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
176 SilcClient client = (SilcClient)ske->user_data;
177 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
179 if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
181 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
182 "We don't support server version `%s'",
184 return SILC_SKE_STATUS_BAD_VERSION;
187 if (!silc_parse_version_string(client->internal->silc_client_version,
188 &l_protocol_version, NULL, NULL,
190 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
191 "We don't support server version `%s'",
193 return SILC_SKE_STATUS_BAD_VERSION;
196 /* If remote is too new, don't connect */
197 if (l_protocol_version < r_protocol_version) {
198 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
199 "We don't support server version `%s'",
201 return SILC_SKE_STATUS_BAD_VERSION;
204 ske->sock->version = r_protocol_version;
206 return SILC_SKE_STATUS_OK;
209 /* Callback that is called by the SKE to indicate that it is safe to
210 continue the execution of the protocol. Is given as argument to the
211 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
212 This is called due to the fact that the public key verification
213 process is asynchronous and we must not continue the protocl until
214 the public key has been verified and this callback is called. */
216 static void silc_client_protocol_ke_continue(SilcSKE ske,
219 SilcProtocol protocol = (SilcProtocol)context;
220 SilcClientKEInternalContext *ctx =
221 (SilcClientKEInternalContext *)protocol->context;
222 SilcClient client = (SilcClient)ctx->client;
223 SilcClientConnection conn = ctx->sock->user_data;
225 SILC_LOG_DEBUG(("Start"));
227 if (ske->status != SILC_SKE_STATUS_OK) {
228 /* Call failure client operation */
229 client->internal->ops->failure(client, conn, protocol,
230 (void *)ske->status);
231 protocol->state = SILC_PROTOCOL_STATE_ERROR;
232 silc_protocol_execute(protocol, client->schedule, 0, 0);
236 /* Send Ok to the other end. We will end the protocol as server
237 sends Ok to us when we will take the new keys into use. Do this
238 if we are initiator. This is happens when this callback was sent
239 to silc_ske_initiator_finish function. */
240 if (ctx->responder == FALSE) {
241 silc_ske_end(ctx->ske);
243 /* End the protocol on the next round */
244 protocol->state = SILC_PROTOCOL_STATE_END;
247 /* Advance protocol state and call the next state if we are responder.
248 This happens when this callback was sent to silc_ske_responder_phase_2
250 if (ctx->responder == TRUE) {
252 silc_protocol_execute(protocol, client->schedule, 0, 1);
256 /* Performs key exchange protocol. This is used for both initiator
257 and responder key exchange. This may be called recursively. */
259 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
261 SilcProtocol protocol = (SilcProtocol)context;
262 SilcClientKEInternalContext *ctx =
263 (SilcClientKEInternalContext *)protocol->context;
264 SilcClient client = (SilcClient)ctx->client;
265 SilcClientConnection conn = ctx->sock->user_data;
266 SilcSKEStatus status = SILC_SKE_STATUS_OK;
268 SILC_LOG_DEBUG(("Start"));
270 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
271 protocol->state = SILC_PROTOCOL_STATE_START;
273 switch(protocol->state) {
274 case SILC_PROTOCOL_STATE_START:
281 /* Allocate Key Exchange object */
282 ctx->ske = ske = silc_ske_alloc(client->rng, client);
284 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
286 silc_client_protocol_ke_continue,
287 silc_ske_check_version,
290 if (ctx->responder == TRUE) {
291 /* Start the key exchange by processing the received security
292 properties packet from initiator. */
294 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
295 client->internal->silc_client_version,
296 ctx->packet->buffer, TRUE);
298 SilcSKEStartPayload *start_payload;
300 /* Assemble security properties. */
301 silc_ske_assemble_security_properties(
302 ske, SILC_SKE_SP_FLAG_MUTUAL,
303 client->internal->silc_client_version,
306 /* Start the key exchange by sending our security properties
307 to the remote end. */
308 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
312 /* Return now if the procedure is pending */
313 if (status == SILC_SKE_STATUS_PENDING)
316 if (status != SILC_SKE_STATUS_OK) {
317 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
319 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
322 protocol->state = SILC_PROTOCOL_STATE_ERROR;
323 silc_protocol_execute(protocol, client->schedule, 0, 0);
327 /* Advance protocol state and call the next state if we are responder */
329 if (ctx->responder == TRUE)
330 silc_protocol_execute(protocol, client->schedule, 0, 1);
338 if (ctx->responder == TRUE) {
339 /* Sends the selected security properties to the initiator. */
340 status = silc_ske_responder_phase_1(ctx->ske);
342 /* Call Phase-1 function. This processes the Key Exchange Start
343 paylaod reply we just got from the responder. The callback
344 function will receive the processed payload where we will
346 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
349 if (status != SILC_SKE_STATUS_OK) {
350 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
352 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
355 protocol->state = SILC_PROTOCOL_STATE_ERROR;
356 silc_protocol_execute(protocol, client->schedule, 0, 0);
360 /* Advance protocol state and call next state if we are initiator */
362 if (ctx->responder == FALSE)
363 silc_protocol_execute(protocol, client->schedule, 0, 1);
371 if (ctx->responder == TRUE) {
372 /* Process the received Key Exchange 1 Payload packet from
373 the initiator. This also creates our parts of the Diffie
374 Hellman algorithm. The silc_client_protocol_ke_continue will
375 be called after the public key has been verified. */
376 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
378 /* Call the Phase-2 function. This creates Diffie Hellman
379 key exchange parameters and sends our public part inside
380 Key Exhange 1 Payload to the responder. */
381 status = silc_ske_initiator_phase_2(ctx->ske,
384 SILC_SKE_PK_TYPE_SILC);
388 /* Return now if the procedure is pending */
389 if (status == SILC_SKE_STATUS_PENDING)
392 if (status != SILC_SKE_STATUS_OK) {
393 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
395 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
398 protocol->state = SILC_PROTOCOL_STATE_ERROR;
399 silc_protocol_execute(protocol, client->schedule, 0, 0);
409 if (ctx->responder == TRUE) {
410 /* This creates the key exchange material and sends our
411 public parts to the initiator inside Key Exchange 2 Payload. */
413 silc_ske_responder_finish(ctx->ske,
414 client->public_key, client->private_key,
415 SILC_SKE_PK_TYPE_SILC);
417 /* End the protocol on the next round */
418 protocol->state = SILC_PROTOCOL_STATE_END;
420 /* Finish the protocol. This verifies the Key Exchange 2 payload
421 sent by responder. The silc_client_protocol_ke_continue will
422 be called after the public key has been verified. */
423 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
426 /* Return now if the procedure is pending */
427 if (status == SILC_SKE_STATUS_PENDING)
430 if (status != SILC_SKE_STATUS_OK) {
431 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
432 client->internal->ops->say(
433 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
434 "Received unsupported server %s public key",
435 ctx->sock->hostname);
437 client->internal->ops->say(
438 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
439 "Error during key exchange protocol with server %s",
440 ctx->sock->hostname);
442 protocol->state = SILC_PROTOCOL_STATE_ERROR;
443 silc_protocol_execute(protocol, client->schedule, 0, 0);
449 case SILC_PROTOCOL_STATE_END:
454 SilcSKEKeyMaterial *keymat;
455 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
456 int hash_len = silc_hash_len(ctx->ske->prop->hash);
458 /* Process the key material */
459 keymat = silc_calloc(1, sizeof(*keymat));
460 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
462 if (status != SILC_SKE_STATUS_OK) {
463 protocol->state = SILC_PROTOCOL_STATE_ERROR;
464 silc_protocol_execute(protocol, client->schedule, 0, 300000);
465 silc_ske_free_key_material(keymat);
468 ctx->keymat = keymat;
470 /* Send Ok to the other end if we are responder. If we are initiator
471 we have sent this already. */
472 if (ctx->responder == TRUE)
473 silc_ske_end(ctx->ske);
475 /* Unregister the timeout task since the protocol has ended.
476 This was the timeout task to be executed if the protocol is
477 not completed fast enough. */
478 if (ctx->timeout_task)
479 silc_schedule_task_del(client->schedule, ctx->timeout_task);
481 /* Protocol has ended, call the final callback */
482 if (protocol->final_callback)
483 silc_protocol_execute_final(protocol, client->schedule);
485 silc_protocol_free(protocol);
489 case SILC_PROTOCOL_STATE_ERROR:
491 * Error during protocol
494 /* Send abort notification */
495 silc_ske_abort(ctx->ske, ctx->ske->status);
497 /* On error the final callback is always called. */
498 if (protocol->final_callback)
499 silc_protocol_execute_final(protocol, client->schedule);
501 silc_protocol_free(protocol);
504 case SILC_PROTOCOL_STATE_FAILURE:
506 * Received failure from remote.
509 /* Unregister the timeout task since the protocol has ended.
510 This was the timeout task to be executed if the protocol is
511 not completed fast enough. */
512 if (ctx->timeout_task)
513 silc_schedule_task_del(client->schedule, ctx->timeout_task);
515 /* On error the final callback is always called. */
516 if (protocol->final_callback)
517 silc_protocol_execute_final(protocol, client->schedule);
519 silc_protocol_free(protocol);
521 case SILC_PROTOCOL_STATE_UNKNOWN:
527 * Connection Authentication protocol functions
531 silc_client_get_public_key_auth(SilcClient client,
532 SilcClientConnection conn,
533 unsigned char *auth_data,
534 SilcUInt32 *auth_data_len,
541 /* Use our default key */
544 /* Make the authentication data. Protocol says it is HASH plus
546 len = ske->hash_len + ske->start_payload_copy->len;
547 auth = silc_buffer_alloc(len);
548 silc_buffer_pull_tail(auth, len);
549 silc_buffer_format(auth,
550 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
551 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
552 ske->start_payload_copy->len),
555 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
556 auth->len, auth_data, auth_data_len)) {
557 silc_buffer_free(auth);
561 silc_buffer_free(auth);
565 /* Continues the connection authentication protocol. This funtion may
566 be called directly or used as SilcAskPassphrase callback. */
569 silc_client_conn_auth_continue(unsigned char *auth_data,
570 SilcUInt32 auth_data_len, void *context)
572 SilcProtocol protocol = (SilcProtocol)context;
573 SilcClientConnAuthInternalContext *ctx =
574 (SilcClientConnAuthInternalContext *)protocol->context;
575 SilcClient client = (SilcClient)ctx->client;
578 unsigned char *autf8 = NULL;
580 SILC_LOG_DEBUG(("Sending authentication to server"));
582 /* Passphrase must be UTF-8 encoded, if it isn't encode it */
583 if (ctx->auth_meth == SILC_AUTH_PASSWORD &&
584 !silc_utf8_valid(auth_data, auth_data_len)) {
585 payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
587 autf8 = silc_calloc(payload_len, sizeof(*autf8));
588 auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
589 SILC_STRING_ASCII, autf8, payload_len);
593 payload_len = 4 + auth_data_len;
594 packet = silc_buffer_alloc(payload_len);
595 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
596 silc_buffer_format(packet,
597 SILC_STR_UI_SHORT(payload_len),
598 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
599 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
602 /* Send the packet to server */
603 silc_client_packet_send(client, ctx->sock,
604 SILC_PACKET_CONNECTION_AUTH,
606 packet->data, packet->len, TRUE);
607 silc_buffer_free(packet);
610 /* Next state is end of protocol */
611 protocol->state = SILC_PROTOCOL_STATE_END;
614 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
616 SilcProtocol protocol = (SilcProtocol)context;
617 SilcClientConnAuthInternalContext *ctx =
618 (SilcClientConnAuthInternalContext *)protocol->context;
619 SilcClient client = (SilcClient)ctx->client;
620 SilcClientConnection conn = ctx->sock->user_data;
622 SILC_LOG_DEBUG(("Start"));
624 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
625 protocol->state = SILC_PROTOCOL_STATE_START;
627 switch(protocol->state) {
628 case SILC_PROTOCOL_STATE_START:
631 * Start protocol. We send authentication data to the server
632 * to be authenticated.
634 unsigned char *auth_data = NULL;
635 SilcUInt32 auth_data_len = 0;
636 unsigned char sign[1024];
638 switch(ctx->auth_meth) {
640 /* No authentication required */
643 case SILC_AUTH_PASSWORD:
644 /* Password authentication */
645 if (ctx->auth_data && ctx->auth_data_len) {
646 auth_data = ctx->auth_data;
647 auth_data_len = ctx->auth_data_len;
651 client->internal->ops->say(
652 client, conn, SILC_CLIENT_MESSAGE_INFO,
653 "Password authentication required by server %s",
654 ctx->sock->hostname);
655 client->internal->ops->ask_passphrase(client, conn,
656 silc_client_conn_auth_continue,
661 case SILC_AUTH_PUBLIC_KEY:
662 if (!ctx->auth_data) {
663 /* Public key authentication */
664 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
668 auth_data = ctx->auth_data;
669 auth_data_len = ctx->auth_data_len;
675 silc_client_conn_auth_continue(auth_data,
676 auth_data_len, protocol);
680 case SILC_PROTOCOL_STATE_END:
683 * End protocol. Nothing special to be done here.
686 /* Protocol has ended, call the final callback */
687 if (protocol->final_callback)
688 silc_protocol_execute_final(protocol, client->schedule);
690 silc_protocol_free(protocol);
694 case SILC_PROTOCOL_STATE_ERROR:
697 * Error. Send notify to remote.
699 unsigned char error[4];
701 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
703 /* Error in protocol. Send FAILURE packet. Although I don't think
704 this could ever happen on client side. */
705 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
706 NULL, 0, NULL, NULL, error, 4, TRUE);
708 /* On error the final callback is always called. */
709 if (protocol->final_callback)
710 silc_protocol_execute_final(protocol, client->schedule);
712 silc_protocol_free(protocol);
715 case SILC_PROTOCOL_STATE_FAILURE:
717 * Received failure from remote.
720 /* On error the final callback is always called. */
721 if (protocol->final_callback)
722 silc_protocol_execute_final(protocol, client->schedule);
724 silc_protocol_free(protocol);
727 case SILC_PROTOCOL_STATE_UNKNOWN:
733 * Re-key protocol routines
736 /* Actually takes the new keys into use. */
739 silc_client_protocol_rekey_validate(SilcClient client,
740 SilcClientRekeyInternalContext *ctx,
741 SilcSocketConnection sock,
742 SilcSKEKeyMaterial *keymat,
745 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
747 if (ctx->responder == TRUE) {
749 silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
750 keymat->enc_key_len);
751 silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv);
752 silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
753 keymat->hmac_key_len);
755 silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
756 keymat->enc_key_len);
757 silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv);
758 silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
759 keymat->hmac_key_len);
763 silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
764 keymat->enc_key_len);
765 silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv);
766 silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
767 keymat->hmac_key_len);
769 silc_cipher_set_key(conn->internal->receive_key,
770 keymat->receive_enc_key, keymat->enc_key_len);
771 silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv);
772 silc_hmac_set_key(conn->internal->hmac_receive,
773 keymat->receive_hmac_key, keymat->hmac_key_len);
777 /* Save the current sending encryption key */
779 memset(conn->internal->rekey->send_enc_key, 0,
780 conn->internal->rekey->enc_key_len);
781 silc_free(conn->internal->rekey->send_enc_key);
782 conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
783 keymat->enc_key_len / 8);
784 conn->internal->rekey->enc_key_len = keymat->enc_key_len / 8;
788 /* This function actually re-generates (when not using PFS) the keys and
789 takes them into use. */
792 silc_client_protocol_rekey_generate(SilcClient client,
793 SilcClientRekeyInternalContext *ctx,
796 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
797 SilcSKEKeyMaterial *keymat;
798 SilcUInt32 key_len = silc_cipher_get_key_len(conn->internal->send_key);
799 SilcUInt32 hash_len = silc_hash_len(conn->internal->hash);
801 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
802 send ? "sending" : "receiving"));
804 /* Generate the new key */
805 keymat = silc_calloc(1, sizeof(*keymat));
806 silc_ske_process_key_material_data(conn->internal->rekey->send_enc_key,
807 conn->internal->rekey->enc_key_len,
808 16, key_len, hash_len,
809 conn->internal->hash, keymat);
811 /* Set the keys into use */
812 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
814 silc_ske_free_key_material(keymat);
817 /* This function actually re-generates (with PFS) the keys and
818 takes them into use. */
821 silc_client_protocol_rekey_generate_pfs(SilcClient client,
822 SilcClientRekeyInternalContext *ctx,
825 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
826 SilcSKEKeyMaterial *keymat;
827 SilcUInt32 key_len = silc_cipher_get_key_len(conn->internal->send_key);
828 SilcUInt32 hash_len = silc_hash_len(conn->internal->hash);
829 unsigned char *tmpbuf;
832 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
833 send ? "sending" : "receiving"));
835 /* Encode KEY to binary data */
836 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
838 /* Generate the new key */
839 keymat = silc_calloc(1, sizeof(*keymat));
840 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
841 conn->internal->hash, keymat);
843 /* Set the keys into use */
844 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
846 memset(tmpbuf, 0, klen);
848 silc_ske_free_key_material(keymat);
851 /* Packet sending callback. This function is provided as packet sending
852 routine to the Key Exchange functions. */
855 silc_client_protocol_rekey_send_packet(SilcSKE ske,
860 SilcProtocol protocol = (SilcProtocol)context;
861 SilcClientRekeyInternalContext *ctx =
862 (SilcClientRekeyInternalContext *)protocol->context;
863 SilcClient client = (SilcClient)ctx->client;
865 /* Send the packet immediately */
866 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
867 packet->data, packet->len, FALSE);
870 /* Performs re-key as defined in the SILC protocol specification. */
872 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
874 SilcProtocol protocol = (SilcProtocol)context;
875 SilcClientRekeyInternalContext *ctx =
876 (SilcClientRekeyInternalContext *)protocol->context;
877 SilcClient client = (SilcClient)ctx->client;
878 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
879 SilcSKEStatus status;
881 SILC_LOG_DEBUG(("Start"));
883 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
884 protocol->state = SILC_PROTOCOL_STATE_START;
886 SILC_LOG_DEBUG(("State=%d", protocol->state));
888 switch(protocol->state) {
889 case SILC_PROTOCOL_STATE_START:
895 if (ctx->responder == TRUE) {
897 * We are receiving party
900 if (ctx->pfs == TRUE) {
902 * Use Perfect Forward Secrecy, ie. negotiate the key material
903 * using the SKE protocol.
906 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
907 /* Error in protocol */
908 protocol->state = SILC_PROTOCOL_STATE_ERROR;
909 silc_protocol_execute(protocol, client->schedule, 0, 300000);
912 ctx->ske = silc_ske_alloc(client->rng, client);
913 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
914 silc_ske_group_get_by_number(conn->internal->rekey->ske_group,
915 &ctx->ske->prop->group);
917 silc_ske_set_callbacks(ctx->ske,
918 silc_client_protocol_rekey_send_packet,
919 NULL, NULL, NULL, silc_ske_check_version,
922 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
923 if (status != SILC_SKE_STATUS_OK) {
924 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
927 protocol->state = SILC_PROTOCOL_STATE_ERROR;
928 silc_protocol_execute(protocol, client->schedule, 0, 300000);
932 /* Advance the protocol state */
934 silc_protocol_execute(protocol, client->schedule, 0, 0);
937 * Do normal and simple re-key.
940 /* Send the REKEY_DONE to indicate we will take new keys into use */
941 silc_client_packet_send(client, ctx->sock,
942 SILC_PACKET_REKEY_DONE,
943 NULL, 0, NULL, NULL, NULL, 0, FALSE);
945 /* After we send REKEY_DONE we must set the sending encryption
946 key to the new key since all packets after this packet must
947 encrypted with the new key. */
948 silc_client_protocol_rekey_generate(client, ctx, TRUE);
950 /* The protocol ends in next stage. */
951 protocol->state = SILC_PROTOCOL_STATE_END;
956 * We are the initiator of this protocol
959 /* Start the re-key by sending the REKEY packet */
960 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
961 NULL, 0, NULL, NULL, NULL, 0, FALSE);
963 if (ctx->pfs == TRUE) {
965 * Use Perfect Forward Secrecy, ie. negotiate the key material
966 * using the SKE protocol.
968 ctx->ske = silc_ske_alloc(client->rng, client);
969 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
970 silc_ske_group_get_by_number(conn->internal->rekey->ske_group,
971 &ctx->ske->prop->group);
973 silc_ske_set_callbacks(ctx->ske,
974 silc_client_protocol_rekey_send_packet,
975 NULL, NULL, NULL, silc_ske_check_version,
978 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
979 if (status != SILC_SKE_STATUS_OK) {
980 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
983 protocol->state = SILC_PROTOCOL_STATE_ERROR;
984 silc_protocol_execute(protocol, client->schedule, 0, 300000);
988 /* Advance the protocol state */
992 * Do normal and simple re-key.
995 /* Send the REKEY_DONE to indicate we will take new keys into use
997 silc_client_packet_send(client, ctx->sock,
998 SILC_PACKET_REKEY_DONE,
999 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1001 /* After we send REKEY_DONE we must set the sending encryption
1002 key to the new key since all packets after this packet must
1003 encrypted with the new key. */
1004 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1006 /* The protocol ends in next stage. */
1007 protocol->state = SILC_PROTOCOL_STATE_END;
1015 * Second state, used only when oding re-key with PFS.
1017 if (ctx->responder == TRUE) {
1018 if (ctx->pfs == TRUE) {
1020 * Send our KE packe to the initiator now that we've processed
1021 * the initiator's KE packet.
1023 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1024 SILC_SKE_PK_TYPE_SILC);
1026 if (status != SILC_SKE_STATUS_OK) {
1027 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1030 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1031 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1037 if (ctx->pfs == TRUE) {
1039 * The packet type must be KE packet
1041 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1042 /* Error in protocol */
1043 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1044 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1047 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1048 if (status != SILC_SKE_STATUS_OK) {
1049 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1052 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1053 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1059 /* Send the REKEY_DONE to indicate we will take new keys into use
1061 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1062 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1064 /* After we send REKEY_DONE we must set the sending encryption
1065 key to the new key since all packets after this packet must
1066 encrypted with the new key. */
1067 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1069 /* The protocol ends in next stage. */
1070 protocol->state = SILC_PROTOCOL_STATE_END;
1073 case SILC_PROTOCOL_STATE_END:
1078 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1079 /* Error in protocol */
1080 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1081 silc_protocol_execute(protocol, client->schedule, 0, 0);
1084 /* We received the REKEY_DONE packet and all packets after this is
1085 encrypted with the new key so set the decryption key to the new key */
1086 if (ctx->pfs == TRUE)
1087 silc_client_protocol_rekey_generate_pfs(client, ctx, FALSE);
1089 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1091 /* Protocol has ended, call the final callback */
1092 if (protocol->final_callback)
1093 silc_protocol_execute_final(protocol, client->schedule);
1095 silc_protocol_free(protocol);
1098 case SILC_PROTOCOL_STATE_ERROR:
1103 if (ctx->pfs == TRUE) {
1104 /* Send abort notification */
1105 silc_ske_abort(ctx->ske, ctx->ske->status);
1108 /* On error the final callback is always called. */
1109 if (protocol->final_callback)
1110 silc_protocol_execute_final(protocol, client->schedule);
1112 silc_protocol_free(protocol);
1115 case SILC_PROTOCOL_STATE_FAILURE:
1117 * We have received failure from remote
1120 /* On error the final callback is always called. */
1121 if (protocol->final_callback)
1122 silc_protocol_execute_final(protocol, client->schedule);
1124 silc_protocol_free(protocol);
1127 case SILC_PROTOCOL_STATE_UNKNOWN:
1133 /* Registers protocols used in client */
1135 void silc_client_protocols_register(void)
1137 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1138 silc_client_protocol_connection_auth);
1139 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1140 silc_client_protocol_key_exchange);
1141 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1142 silc_client_protocol_rekey);
1145 /* Unregisters protocols */
1147 void silc_client_protocols_unregister(void)
1149 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1150 silc_client_protocol_connection_auth);
1151 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1152 silc_client_protocol_key_exchange);
1153 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1154 silc_client_protocol_rekey);