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);
33 * Key Exhange protocol functions
36 /* Function that is called when SKE protocol sends packets to network. */
38 void silc_client_protocol_ke_send_packet(SilcSKE ske,
43 SilcProtocol protocol = (SilcProtocol)context;
44 SilcClientKEInternalContext *ctx =
45 (SilcClientKEInternalContext *)protocol->context;
46 SilcClient client = (SilcClient)ctx->client;
48 /* Send the packet immediately */
49 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
50 packet->data, packet->len, TRUE);
53 /* Public key verification callback. Called by the application. */
57 SilcSKEVerifyCbCompletion completion;
58 void *completion_context;
61 static void silc_client_verify_key_cb(bool success, void *context)
63 VerifyKeyContext verify = (VerifyKeyContext)context;
65 SILC_LOG_DEBUG(("Start"));
67 /* Call the completion callback back to the SKE */
68 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
69 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
70 verify->completion_context);
75 /* Callback that is called when we have received KE payload from
76 responder. We try to verify the public key now. */
78 void silc_client_protocol_ke_verify_key(SilcSKE ske,
79 unsigned char *pk_data,
81 SilcSKEPKType pk_type,
83 SilcSKEVerifyCbCompletion completion,
84 void *completion_context)
86 SilcProtocol protocol = (SilcProtocol)context;
87 SilcClientKEInternalContext *ctx =
88 (SilcClientKEInternalContext *)protocol->context;
89 SilcClient client = (SilcClient)ctx->client;
90 VerifyKeyContext verify;
92 SILC_LOG_DEBUG(("Start"));
94 verify = silc_calloc(1, sizeof(*verify));
96 verify->completion = completion;
97 verify->completion_context = completion_context;
99 /* Verify public key from user. */
100 client->internal->ops->verify_public_key(client, ctx->sock->user_data,
102 pk_data, pk_len, pk_type,
103 silc_client_verify_key_cb, verify);
106 /* Sets the negotiated key material into use for particular connection. */
108 void silc_client_protocol_ke_set_keys(SilcSKE ske,
109 SilcSocketConnection sock,
110 SilcSKEKeyMaterial *keymat,
115 SilcSKEDiffieHellmanGroup group,
118 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
120 SILC_LOG_DEBUG(("Setting new keys into use"));
122 /* Allocate cipher to be used in the communication */
123 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
124 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
125 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
126 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
128 if (is_responder == TRUE) {
129 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
130 keymat->enc_key_len);
131 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
132 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
133 keymat->enc_key_len);
134 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
135 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
136 keymat->hmac_key_len);
137 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
138 keymat->hmac_key_len);
140 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
141 keymat->enc_key_len);
142 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
143 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
144 keymat->enc_key_len);
145 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
146 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
147 keymat->hmac_key_len);
148 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
149 keymat->hmac_key_len);
153 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
154 conn->rekey->send_enc_key =
155 silc_calloc(keymat->enc_key_len / 8,
156 sizeof(*conn->rekey->send_enc_key));
157 memcpy(conn->rekey->send_enc_key,
158 keymat->send_enc_key, keymat->enc_key_len / 8);
159 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
161 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
162 conn->rekey->pfs = TRUE;
163 conn->rekey->ske_group = silc_ske_group_get_number(group);
165 /* Save the HASH function */
166 silc_hash_alloc(hash->hash->name, &conn->hash);
169 /* Checks the version string of the server. */
171 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
172 uint32 len, void *context)
174 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
175 SilcClient client = (SilcClient)ske->user_data;
176 SilcSKEStatus status = SILC_SKE_STATUS_OK;
178 int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
180 /* Check for initial version string */
181 if (!strstr(version, "SILC-1.0-"))
182 status = SILC_SKE_STATUS_BAD_VERSION;
184 /* Check software version */
188 status = SILC_SKE_STATUS_BAD_VERSION;
191 cp = strchr(cp, '.');
196 cp = strchr(cp, '.');
198 build = atoi(cp + 1);
200 cp = client->internal->silc_client_version + 9;
202 status = SILC_SKE_STATUS_BAD_VERSION;
205 cp = strchr(cp, '.');
210 cp = strchr(cp, '.');
212 build2 = atoi(cp + 1);
215 status = SILC_SKE_STATUS_BAD_VERSION;
217 /* XXX backward support for 0.6.1 */
218 if (maj == 0 && min == 6 && build < 2)
219 ske->backward_version = 1;
221 if (status != SILC_SKE_STATUS_OK)
222 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
223 "We don't support server version `%s'",
229 /* Callback that is called by the SKE to indicate that it is safe to
230 continue the execution of the protocol. Is given as argument to the
231 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
232 This is called due to the fact that the public key verification
233 process is asynchronous and we must not continue the protocl until
234 the public key has been verified and this callback is called. */
236 static void silc_client_protocol_ke_continue(SilcSKE ske,
239 SilcProtocol protocol = (SilcProtocol)context;
240 SilcClientKEInternalContext *ctx =
241 (SilcClientKEInternalContext *)protocol->context;
242 SilcClient client = (SilcClient)ctx->client;
243 SilcClientConnection conn = ctx->sock->user_data;
245 SILC_LOG_DEBUG(("Start"));
247 if (ske->status != SILC_SKE_STATUS_OK) {
248 /* Call failure client operation */
249 client->internal->ops->failure(client, conn, protocol,
250 (void *)ske->status);
251 protocol->state = SILC_PROTOCOL_STATE_ERROR;
252 silc_protocol_execute(protocol, client->schedule, 0, 0);
256 /* Send Ok to the other end. We will end the protocol as server
257 sends Ok to us when we will take the new keys into use. Do this
258 if we are initiator. This is happens when this callback was sent
259 to silc_ske_initiator_finish function. */
260 if (ctx->responder == FALSE) {
261 silc_ske_end(ctx->ske);
263 /* End the protocol on the next round */
264 protocol->state = SILC_PROTOCOL_STATE_END;
267 /* Advance protocol state and call the next state if we are responder.
268 This happens when this callback was sent to silc_ske_responder_phase_2
270 if (ctx->responder == TRUE) {
272 silc_protocol_execute(protocol, client->schedule, 0, 100000);
276 /* Performs key exchange protocol. This is used for both initiator
277 and responder key exchange. This may be called recursively. */
279 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
281 SilcProtocol protocol = (SilcProtocol)context;
282 SilcClientKEInternalContext *ctx =
283 (SilcClientKEInternalContext *)protocol->context;
284 SilcClient client = (SilcClient)ctx->client;
285 SilcClientConnection conn = ctx->sock->user_data;
286 SilcSKEStatus status = SILC_SKE_STATUS_OK;
288 SILC_LOG_DEBUG(("Start"));
290 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
291 protocol->state = SILC_PROTOCOL_STATE_START;
293 switch(protocol->state) {
294 case SILC_PROTOCOL_STATE_START:
301 /* Allocate Key Exchange object */
302 ctx->ske = ske = silc_ske_alloc(client->rng, client);
304 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
306 silc_client_protocol_ke_continue,
307 silc_ske_check_version,
310 if (ctx->responder == TRUE) {
311 /* Start the key exchange by processing the received security
312 properties packet from initiator. */
314 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
315 client->internal->silc_client_version,
316 ctx->packet->buffer, TRUE);
318 SilcSKEStartPayload *start_payload;
320 /* Assemble security properties. */
321 silc_ske_assemble_security_properties(
322 ske, SILC_SKE_SP_FLAG_MUTUAL,
323 client->internal->silc_client_version,
326 /* Start the key exchange by sending our security properties
327 to the remote end. */
328 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
332 /* Return now if the procedure is pending */
333 if (status == SILC_SKE_STATUS_PENDING)
336 if (status != SILC_SKE_STATUS_OK) {
337 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
339 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
342 protocol->state = SILC_PROTOCOL_STATE_ERROR;
343 silc_protocol_execute(protocol, client->schedule, 0, 0);
347 /* Advance protocol state and call the next state if we are responder */
349 if (ctx->responder == TRUE)
350 silc_protocol_execute(protocol, client->schedule, 0, 100000);
358 if (ctx->responder == TRUE) {
359 /* Sends the selected security properties to the initiator. */
360 status = silc_ske_responder_phase_1(ctx->ske);
362 /* Call Phase-1 function. This processes the Key Exchange Start
363 paylaod reply we just got from the responder. The callback
364 function will receive the processed payload where we will
366 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
369 if (status != SILC_SKE_STATUS_OK) {
370 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
372 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
375 protocol->state = SILC_PROTOCOL_STATE_ERROR;
376 silc_protocol_execute(protocol, client->schedule, 0, 0);
380 /* Advance protocol state and call next state if we are initiator */
382 if (ctx->responder == FALSE)
383 silc_protocol_execute(protocol, client->schedule, 0, 100000);
391 if (ctx->responder == TRUE) {
392 /* Process the received Key Exchange 1 Payload packet from
393 the initiator. This also creates our parts of the Diffie
394 Hellman algorithm. The silc_client_protocol_ke_continue will
395 be called after the public key has been verified. */
396 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
398 /* Call the Phase-2 function. This creates Diffie Hellman
399 key exchange parameters and sends our public part inside
400 Key Exhange 1 Payload to the responder. */
401 status = silc_ske_initiator_phase_2(ctx->ske,
404 SILC_SKE_PK_TYPE_SILC);
408 /* Return now if the procedure is pending */
409 if (status == SILC_SKE_STATUS_PENDING)
412 if (status != SILC_SKE_STATUS_OK) {
413 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
415 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
418 protocol->state = SILC_PROTOCOL_STATE_ERROR;
419 silc_protocol_execute(protocol, client->schedule, 0, 0);
429 if (ctx->responder == TRUE) {
430 /* This creates the key exchange material and sends our
431 public parts to the initiator inside Key Exchange 2 Payload. */
433 silc_ske_responder_finish(ctx->ske,
434 client->public_key, client->private_key,
435 SILC_SKE_PK_TYPE_SILC);
437 /* End the protocol on the next round */
438 protocol->state = SILC_PROTOCOL_STATE_END;
440 /* Finish the protocol. This verifies the Key Exchange 2 payload
441 sent by responder. The silc_client_protocol_ke_continue will
442 be called after the public key has been verified. */
443 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
446 /* Return now if the procedure is pending */
447 if (status == SILC_SKE_STATUS_PENDING)
450 if (status != SILC_SKE_STATUS_OK) {
451 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
452 client->internal->ops->say(
453 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
454 "Received unsupported server %s public key",
455 ctx->sock->hostname);
457 client->internal->ops->say(
458 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
459 "Error during key exchange protocol with server %s",
460 ctx->sock->hostname);
462 protocol->state = SILC_PROTOCOL_STATE_ERROR;
463 silc_protocol_execute(protocol, client->schedule, 0, 0);
469 case SILC_PROTOCOL_STATE_END:
474 SilcSKEKeyMaterial *keymat;
475 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
476 int hash_len = ctx->ske->prop->hash->hash->hash_len;
478 /* Process the key material */
479 keymat = silc_calloc(1, sizeof(*keymat));
480 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
482 if (status != SILC_SKE_STATUS_OK) {
483 protocol->state = SILC_PROTOCOL_STATE_ERROR;
484 silc_protocol_execute(protocol, client->schedule, 0, 300000);
485 silc_ske_free_key_material(keymat);
488 ctx->keymat = keymat;
490 /* Send Ok to the other end if we are responder. If we are initiator
491 we have sent this already. */
492 if (ctx->responder == TRUE)
493 silc_ske_end(ctx->ske);
495 /* Unregister the timeout task since the protocol has ended.
496 This was the timeout task to be executed if the protocol is
497 not completed fast enough. */
498 if (ctx->timeout_task)
499 silc_schedule_task_del(client->schedule, ctx->timeout_task);
501 /* Protocol has ended, call the final callback */
502 if (protocol->final_callback)
503 silc_protocol_execute_final(protocol, client->schedule);
505 silc_protocol_free(protocol);
509 case SILC_PROTOCOL_STATE_ERROR:
511 * Error during protocol
514 /* Send abort notification */
515 silc_ske_abort(ctx->ske, ctx->ske->status);
517 /* On error the final callback is always called. */
518 if (protocol->final_callback)
519 silc_protocol_execute_final(protocol, client->schedule);
521 silc_protocol_free(protocol);
524 case SILC_PROTOCOL_STATE_FAILURE:
526 * Received failure from remote.
529 /* Unregister the timeout task since the protocol has ended.
530 This was the timeout task to be executed if the protocol is
531 not completed fast enough. */
532 if (ctx->timeout_task)
533 silc_schedule_task_del(client->schedule, ctx->timeout_task);
535 /* On error the final callback is always called. */
536 if (protocol->final_callback)
537 silc_protocol_execute_final(protocol, client->schedule);
539 silc_protocol_free(protocol);
541 case SILC_PROTOCOL_STATE_UNKNOWN:
547 * Connection Authentication protocol functions
551 silc_client_get_public_key_auth(SilcClient client,
552 SilcClientConnection conn,
553 unsigned char *auth_data,
554 uint32 *auth_data_len,
561 /* Use our default key */
564 /* Make the authentication data. Protocol says it is HASH plus
566 len = ske->hash_len + ske->start_payload_copy->len;
567 auth = silc_buffer_alloc(len);
568 silc_buffer_pull_tail(auth, len);
569 silc_buffer_format(auth,
570 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
571 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
572 ske->start_payload_copy->len),
575 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
576 auth->len, auth_data, auth_data_len)) {
577 silc_buffer_free(auth);
581 silc_buffer_free(auth);
585 /* Continues the connection authentication protocol. This funtion may
586 be called directly or used as SilcAskPassphrase callback. */
589 silc_client_conn_auth_continue(unsigned char *auth_data,
590 uint32 auth_data_len, void *context)
592 SilcProtocol protocol = (SilcProtocol)context;
593 SilcClientConnAuthInternalContext *ctx =
594 (SilcClientConnAuthInternalContext *)protocol->context;
595 SilcClient client = (SilcClient)ctx->client;
599 SILC_LOG_DEBUG(("Start"));
601 payload_len = 4 + auth_data_len;
602 packet = silc_buffer_alloc(payload_len);
603 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
604 silc_buffer_format(packet,
605 SILC_STR_UI_SHORT(payload_len),
606 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
607 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
610 /* Send the packet to server */
611 silc_client_packet_send(client, ctx->sock,
612 SILC_PACKET_CONNECTION_AUTH,
614 packet->data, packet->len, TRUE);
615 silc_buffer_free(packet);
617 /* Next state is end of protocol */
618 protocol->state = SILC_PROTOCOL_STATE_END;
621 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
623 SilcProtocol protocol = (SilcProtocol)context;
624 SilcClientConnAuthInternalContext *ctx =
625 (SilcClientConnAuthInternalContext *)protocol->context;
626 SilcClient client = (SilcClient)ctx->client;
627 SilcClientConnection conn = ctx->sock->user_data;
629 SILC_LOG_DEBUG(("Start"));
631 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
632 protocol->state = SILC_PROTOCOL_STATE_START;
634 switch(protocol->state) {
635 case SILC_PROTOCOL_STATE_START:
638 * Start protocol. We send authentication data to the server
639 * to be authenticated.
641 unsigned char *auth_data = NULL;
642 uint32 auth_data_len = 0;
643 unsigned char sign[1024];
645 switch(ctx->auth_meth) {
647 /* No authentication required */
650 case SILC_AUTH_PASSWORD:
651 /* Password authentication */
652 if (ctx->auth_data && ctx->auth_data_len) {
653 auth_data = ctx->auth_data;
654 auth_data_len = ctx->auth_data_len;
658 client->internal->ops->say(
659 client, conn, SILC_CLIENT_MESSAGE_INFO,
660 "Password authentication required by server %s",
661 ctx->sock->hostname);
662 client->internal->ops->ask_passphrase(client, conn,
663 silc_client_conn_auth_continue,
668 case SILC_AUTH_PUBLIC_KEY:
669 if (!ctx->auth_data) {
670 /* Public key authentication */
671 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
675 auth_data = ctx->auth_data;
676 auth_data_len = ctx->auth_data_len;
682 silc_client_conn_auth_continue(auth_data,
683 auth_data_len, protocol);
687 case SILC_PROTOCOL_STATE_END:
690 * End protocol. Nothing special to be done here.
693 /* Protocol has ended, call the final callback */
694 if (protocol->final_callback)
695 silc_protocol_execute_final(protocol, client->schedule);
697 silc_protocol_free(protocol);
701 case SILC_PROTOCOL_STATE_ERROR:
704 * Error. Send notify to remote.
706 unsigned char error[4];
708 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
710 /* Error in protocol. Send FAILURE packet. Although I don't think
711 this could ever happen on client side. */
712 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
713 NULL, 0, NULL, NULL, error, 4, TRUE);
715 /* On error the final callback is always called. */
716 if (protocol->final_callback)
717 silc_protocol_execute_final(protocol, client->schedule);
719 silc_protocol_free(protocol);
722 case SILC_PROTOCOL_STATE_FAILURE:
724 * Received failure from remote.
727 /* On error the final callback is always called. */
728 if (protocol->final_callback)
729 silc_protocol_execute_final(protocol, client->schedule);
731 silc_protocol_free(protocol);
734 case SILC_PROTOCOL_STATE_UNKNOWN:
740 * Re-key protocol routines
743 /* Actually takes the new keys into use. */
746 silc_client_protocol_rekey_validate(SilcClient client,
747 SilcClientRekeyInternalContext *ctx,
748 SilcSocketConnection sock,
749 SilcSKEKeyMaterial *keymat,
752 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
754 if (ctx->responder == TRUE) {
756 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
757 keymat->enc_key_len);
758 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
759 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
760 keymat->hmac_key_len);
762 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
763 keymat->enc_key_len);
764 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
765 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
766 keymat->hmac_key_len);
770 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
771 keymat->enc_key_len);
772 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
773 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
774 keymat->hmac_key_len);
776 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
777 keymat->enc_key_len);
778 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
779 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
780 keymat->hmac_key_len);
784 /* Save the current sending encryption key */
786 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
787 silc_free(conn->rekey->send_enc_key);
788 conn->rekey->send_enc_key =
789 silc_calloc(keymat->enc_key_len / 8,
790 sizeof(*conn->rekey->send_enc_key));
791 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
792 keymat->enc_key_len / 8);
793 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
797 /* This function actually re-generates (when not using PFS) the keys and
798 takes them into use. */
801 silc_client_protocol_rekey_generate(SilcClient client,
802 SilcClientRekeyInternalContext *ctx,
805 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
806 SilcSKEKeyMaterial *keymat;
807 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
808 uint32 hash_len = conn->hash->hash->hash_len;
810 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
811 send ? "sending" : "receiving"));
813 /* Generate the new key */
814 keymat = silc_calloc(1, sizeof(*keymat));
815 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
816 conn->rekey->enc_key_len,
817 16, key_len, hash_len,
820 /* Set the keys into use */
821 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
823 silc_ske_free_key_material(keymat);
826 /* This function actually re-generates (with PFS) the keys and
827 takes them into use. */
830 silc_client_protocol_rekey_generate_pfs(SilcClient client,
831 SilcClientRekeyInternalContext *ctx,
834 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
835 SilcSKEKeyMaterial *keymat;
836 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
837 uint32 hash_len = conn->hash->hash->hash_len;
838 unsigned char *tmpbuf;
841 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
842 send ? "sending" : "receiving"));
844 /* Encode KEY to binary data */
845 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
847 /* Generate the new key */
848 keymat = silc_calloc(1, sizeof(*keymat));
849 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
852 /* Set the keys into use */
853 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
855 memset(tmpbuf, 0, klen);
857 silc_ske_free_key_material(keymat);
860 /* Packet sending callback. This function is provided as packet sending
861 routine to the Key Exchange functions. */
864 silc_client_protocol_rekey_send_packet(SilcSKE ske,
869 SilcProtocol protocol = (SilcProtocol)context;
870 SilcClientRekeyInternalContext *ctx =
871 (SilcClientRekeyInternalContext *)protocol->context;
872 SilcClient client = (SilcClient)ctx->client;
874 /* Send the packet immediately */
875 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
876 packet->data, packet->len, FALSE);
879 /* Performs re-key as defined in the SILC protocol specification. */
881 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
883 SilcProtocol protocol = (SilcProtocol)context;
884 SilcClientRekeyInternalContext *ctx =
885 (SilcClientRekeyInternalContext *)protocol->context;
886 SilcClient client = (SilcClient)ctx->client;
887 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
888 SilcSKEStatus status;
890 SILC_LOG_DEBUG(("Start"));
892 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
893 protocol->state = SILC_PROTOCOL_STATE_START;
895 SILC_LOG_DEBUG(("State=%d", protocol->state));
897 switch(protocol->state) {
898 case SILC_PROTOCOL_STATE_START:
904 if (ctx->responder == TRUE) {
906 * We are receiving party
909 if (ctx->pfs == TRUE) {
911 * Use Perfect Forward Secrecy, ie. negotiate the key material
912 * using the SKE protocol.
915 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
916 /* Error in protocol */
917 protocol->state = SILC_PROTOCOL_STATE_ERROR;
918 silc_protocol_execute(protocol, client->schedule, 0, 300000);
921 ctx->ske = silc_ske_alloc(client->rng, client);
922 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
923 silc_ske_group_get_by_number(conn->rekey->ske_group,
924 &ctx->ske->prop->group);
926 silc_ske_set_callbacks(ctx->ske,
927 silc_client_protocol_rekey_send_packet,
928 NULL, NULL, NULL, silc_ske_check_version,
931 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
932 if (status != SILC_SKE_STATUS_OK) {
933 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
936 protocol->state = SILC_PROTOCOL_STATE_ERROR;
937 silc_protocol_execute(protocol, client->schedule, 0, 300000);
941 /* Advance the protocol state */
943 silc_protocol_execute(protocol, client->schedule, 0, 0);
946 * Do normal and simple re-key.
949 /* Send the REKEY_DONE to indicate we will take new keys into use */
950 silc_client_packet_send(client, ctx->sock,
951 SILC_PACKET_REKEY_DONE,
952 NULL, 0, NULL, NULL, NULL, 0, FALSE);
954 /* After we send REKEY_DONE we must set the sending encryption
955 key to the new key since all packets after this packet must
956 encrypted with the new key. */
957 silc_client_protocol_rekey_generate(client, ctx, TRUE);
959 /* The protocol ends in next stage. */
960 protocol->state = SILC_PROTOCOL_STATE_END;
965 * We are the initiator of this protocol
968 /* Start the re-key by sending the REKEY packet */
969 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
970 NULL, 0, NULL, NULL, NULL, 0, FALSE);
972 if (ctx->pfs == TRUE) {
974 * Use Perfect Forward Secrecy, ie. negotiate the key material
975 * using the SKE protocol.
977 ctx->ske = silc_ske_alloc(client->rng, client);
978 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
979 silc_ske_group_get_by_number(conn->rekey->ske_group,
980 &ctx->ske->prop->group);
982 silc_ske_set_callbacks(ctx->ske,
983 silc_client_protocol_rekey_send_packet,
984 NULL, NULL, NULL, silc_ske_check_version,
987 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
988 if (status != SILC_SKE_STATUS_OK) {
989 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
992 protocol->state = SILC_PROTOCOL_STATE_ERROR;
993 silc_protocol_execute(protocol, client->schedule, 0, 300000);
997 /* Advance the protocol state */
1001 * Do normal and simple re-key.
1004 /* Send the REKEY_DONE to indicate we will take new keys into use
1006 silc_client_packet_send(client, ctx->sock,
1007 SILC_PACKET_REKEY_DONE,
1008 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1010 /* After we send REKEY_DONE we must set the sending encryption
1011 key to the new key since all packets after this packet must
1012 encrypted with the new key. */
1013 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1015 /* The protocol ends in next stage. */
1016 protocol->state = SILC_PROTOCOL_STATE_END;
1024 * Second state, used only when oding re-key with PFS.
1026 if (ctx->responder == TRUE) {
1027 if (ctx->pfs == TRUE) {
1029 * Send our KE packe to the initiator now that we've processed
1030 * the initiator's KE packet.
1032 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1033 SILC_SKE_PK_TYPE_SILC);
1035 if (status != SILC_SKE_STATUS_OK) {
1036 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1039 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1040 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1046 if (ctx->pfs == TRUE) {
1048 * The packet type must be KE packet
1050 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1051 /* Error in protocol */
1052 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1053 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1056 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1057 if (status != SILC_SKE_STATUS_OK) {
1058 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1061 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1062 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1068 /* Send the REKEY_DONE to indicate we will take new keys into use
1070 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1071 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1073 /* After we send REKEY_DONE we must set the sending encryption
1074 key to the new key since all packets after this packet must
1075 encrypted with the new key. */
1076 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1078 /* The protocol ends in next stage. */
1079 protocol->state = SILC_PROTOCOL_STATE_END;
1082 case SILC_PROTOCOL_STATE_END:
1087 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1088 /* Error in protocol */
1089 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1090 silc_protocol_execute(protocol, client->schedule, 0, 0);
1093 /* We received the REKEY_DONE packet and all packets after this is
1094 encrypted with the new key so set the decryption key to the new key */
1095 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1097 /* Protocol has ended, call the final callback */
1098 if (protocol->final_callback)
1099 silc_protocol_execute_final(protocol, client->schedule);
1101 silc_protocol_free(protocol);
1104 case SILC_PROTOCOL_STATE_ERROR:
1109 if (ctx->pfs == TRUE) {
1110 /* Send abort notification */
1111 silc_ske_abort(ctx->ske, ctx->ske->status);
1114 /* On error the final callback is always called. */
1115 if (protocol->final_callback)
1116 silc_protocol_execute_final(protocol, client->schedule);
1118 silc_protocol_free(protocol);
1121 case SILC_PROTOCOL_STATE_FAILURE:
1123 * We have received failure from remote
1126 /* On error the final callback is always called. */
1127 if (protocol->final_callback)
1128 silc_protocol_execute_final(protocol, client->schedule);
1130 silc_protocol_free(protocol);
1133 case SILC_PROTOCOL_STATE_UNKNOWN:
1139 /* Registers protocols used in client */
1141 void silc_client_protocols_register(void)
1143 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1144 silc_client_protocol_connection_auth);
1145 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1146 silc_client_protocol_key_exchange);
1147 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1148 silc_client_protocol_rekey);
1151 /* Unregisters protocols */
1153 void silc_client_protocols_unregister(void)
1155 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1156 silc_client_protocol_connection_auth);
1157 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1158 silc_client_protocol_key_exchange);
1159 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1160 silc_client_protocol_rekey);