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 ske = silc_ske_alloc();
304 ske->rng = client->rng;
305 ske->user_data = (void *)client;
307 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
309 silc_client_protocol_ke_continue,
310 silc_ske_check_version,
313 if (ctx->responder == TRUE) {
314 /* Start the key exchange by processing the received security
315 properties packet from initiator. */
317 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
318 client->internal->silc_client_version,
319 ctx->packet->buffer, TRUE);
321 SilcSKEStartPayload *start_payload;
323 /* Assemble security properties. */
324 silc_ske_assemble_security_properties(
325 ske, SILC_SKE_SP_FLAG_MUTUAL,
326 client->internal->silc_client_version,
329 /* Start the key exchange by sending our security properties
330 to the remote end. */
331 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
335 /* Return now if the procedure is pending */
336 if (status == SILC_SKE_STATUS_PENDING)
339 if (status != SILC_SKE_STATUS_OK) {
340 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
342 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
345 protocol->state = SILC_PROTOCOL_STATE_ERROR;
346 silc_protocol_execute(protocol, client->schedule, 0, 0);
350 /* Advance protocol state and call the next state if we are responder */
352 if (ctx->responder == TRUE)
353 silc_protocol_execute(protocol, client->schedule, 0, 100000);
361 if (ctx->responder == TRUE) {
362 /* Sends the selected security properties to the initiator. */
364 silc_ske_responder_phase_1(ctx->ske,
365 ctx->ske->start_payload);
367 /* Call Phase-1 function. This processes the Key Exchange Start
368 paylaod reply we just got from the responder. The callback
369 function will receive the processed payload where we will
371 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
374 if (status != SILC_SKE_STATUS_OK) {
375 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
377 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
380 protocol->state = SILC_PROTOCOL_STATE_ERROR;
381 silc_protocol_execute(protocol, client->schedule, 0, 0);
385 /* Advance protocol state and call next state if we are initiator */
387 if (ctx->responder == FALSE)
388 silc_protocol_execute(protocol, client->schedule, 0, 100000);
396 if (ctx->responder == TRUE) {
397 /* Process the received Key Exchange 1 Payload packet from
398 the initiator. This also creates our parts of the Diffie
399 Hellman algorithm. The silc_client_protocol_ke_continue will
400 be called after the public key has been verified. */
401 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
403 /* Call the Phase-2 function. This creates Diffie Hellman
404 key exchange parameters and sends our public part inside
405 Key Exhange 1 Payload to the responder. */
406 status = silc_ske_initiator_phase_2(ctx->ske,
408 client->private_key);
412 /* Return now if the procedure is pending */
413 if (status == SILC_SKE_STATUS_PENDING)
416 if (status != SILC_SKE_STATUS_OK) {
417 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
419 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
422 protocol->state = SILC_PROTOCOL_STATE_ERROR;
423 silc_protocol_execute(protocol, client->schedule, 0, 0);
433 if (ctx->responder == TRUE) {
434 /* This creates the key exchange material and sends our
435 public parts to the initiator inside Key Exchange 2 Payload. */
437 silc_ske_responder_finish(ctx->ske,
438 client->public_key, client->private_key,
439 SILC_SKE_PK_TYPE_SILC);
441 /* End the protocol on the next round */
442 protocol->state = SILC_PROTOCOL_STATE_END;
444 /* Finish the protocol. This verifies the Key Exchange 2 payload
445 sent by responder. The silc_client_protocol_ke_continue will
446 be called after the public key has been verified. */
447 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
450 /* Return now if the procedure is pending */
451 if (status == SILC_SKE_STATUS_PENDING)
454 if (status != SILC_SKE_STATUS_OK) {
455 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
456 client->internal->ops->say(
457 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
458 "Received unsupported server %s public key",
459 ctx->sock->hostname);
461 client->internal->ops->say(
462 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
463 "Error during key exchange protocol with server %s",
464 ctx->sock->hostname);
466 protocol->state = SILC_PROTOCOL_STATE_ERROR;
467 silc_protocol_execute(protocol, client->schedule, 0, 0);
473 case SILC_PROTOCOL_STATE_END:
478 SilcSKEKeyMaterial *keymat;
479 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
480 int hash_len = ctx->ske->prop->hash->hash->hash_len;
482 /* Process the key material */
483 keymat = silc_calloc(1, sizeof(*keymat));
484 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
486 if (status != SILC_SKE_STATUS_OK) {
487 protocol->state = SILC_PROTOCOL_STATE_ERROR;
488 silc_protocol_execute(protocol, client->schedule, 0, 300000);
489 silc_ske_free_key_material(keymat);
492 ctx->keymat = keymat;
494 /* Send Ok to the other end if we are responder. If we are initiator
495 we have sent this already. */
496 if (ctx->responder == TRUE)
497 silc_ske_end(ctx->ske);
499 /* Unregister the timeout task since the protocol has ended.
500 This was the timeout task to be executed if the protocol is
501 not completed fast enough. */
502 if (ctx->timeout_task)
503 silc_schedule_task_del(client->schedule, ctx->timeout_task);
505 /* Protocol has ended, call the final callback */
506 if (protocol->final_callback)
507 silc_protocol_execute_final(protocol, client->schedule);
509 silc_protocol_free(protocol);
513 case SILC_PROTOCOL_STATE_ERROR:
515 * Error during protocol
518 /* Send abort notification */
519 silc_ske_abort(ctx->ske, ctx->ske->status);
521 /* On error the final callback is always called. */
522 if (protocol->final_callback)
523 silc_protocol_execute_final(protocol, client->schedule);
525 silc_protocol_free(protocol);
528 case SILC_PROTOCOL_STATE_FAILURE:
530 * Received failure from remote.
533 /* Unregister the timeout task since the protocol has ended.
534 This was the timeout task to be executed if the protocol is
535 not completed fast enough. */
536 if (ctx->timeout_task)
537 silc_schedule_task_del(client->schedule, ctx->timeout_task);
539 /* On error the final callback is always called. */
540 if (protocol->final_callback)
541 silc_protocol_execute_final(protocol, client->schedule);
543 silc_protocol_free(protocol);
545 case SILC_PROTOCOL_STATE_UNKNOWN:
551 * Connection Authentication protocol functions
555 silc_client_get_public_key_auth(SilcClient client,
556 SilcClientConnection conn,
557 unsigned char *auth_data,
558 uint32 *auth_data_len,
565 /* Use our default key */
568 /* Make the authentication data. Protocol says it is HASH plus
570 len = ske->hash_len + ske->start_payload_copy->len;
571 auth = silc_buffer_alloc(len);
572 silc_buffer_pull_tail(auth, len);
573 silc_buffer_format(auth,
574 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
575 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
576 ske->start_payload_copy->len),
579 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
580 auth->len, auth_data, auth_data_len)) {
581 silc_buffer_free(auth);
585 silc_buffer_free(auth);
589 /* Continues the connection authentication protocol. This funtion may
590 be called directly or used as SilcAskPassphrase callback. */
593 silc_client_conn_auth_continue(unsigned char *auth_data,
594 uint32 auth_data_len, void *context)
596 SilcProtocol protocol = (SilcProtocol)context;
597 SilcClientConnAuthInternalContext *ctx =
598 (SilcClientConnAuthInternalContext *)protocol->context;
599 SilcClient client = (SilcClient)ctx->client;
603 SILC_LOG_DEBUG(("Start"));
605 payload_len = 4 + auth_data_len;
606 packet = silc_buffer_alloc(payload_len);
607 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
608 silc_buffer_format(packet,
609 SILC_STR_UI_SHORT(payload_len),
610 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
611 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
614 /* Send the packet to server */
615 silc_client_packet_send(client, ctx->sock,
616 SILC_PACKET_CONNECTION_AUTH,
618 packet->data, packet->len, TRUE);
619 silc_buffer_free(packet);
621 /* Next state is end of protocol */
622 protocol->state = SILC_PROTOCOL_STATE_END;
625 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
627 SilcProtocol protocol = (SilcProtocol)context;
628 SilcClientConnAuthInternalContext *ctx =
629 (SilcClientConnAuthInternalContext *)protocol->context;
630 SilcClient client = (SilcClient)ctx->client;
631 SilcClientConnection conn = ctx->sock->user_data;
633 SILC_LOG_DEBUG(("Start"));
635 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
636 protocol->state = SILC_PROTOCOL_STATE_START;
638 switch(protocol->state) {
639 case SILC_PROTOCOL_STATE_START:
642 * Start protocol. We send authentication data to the server
643 * to be authenticated.
645 unsigned char *auth_data = NULL;
646 uint32 auth_data_len = 0;
647 unsigned char sign[1024];
649 switch(ctx->auth_meth) {
651 /* No authentication required */
654 case SILC_AUTH_PASSWORD:
655 /* Password authentication */
656 if (ctx->auth_data && ctx->auth_data_len) {
657 auth_data = ctx->auth_data;
658 auth_data_len = ctx->auth_data_len;
662 client->internal->ops->say(
663 client, conn, SILC_CLIENT_MESSAGE_INFO,
664 "Password authentication required by server %s",
665 ctx->sock->hostname);
666 client->internal->ops->ask_passphrase(client, conn,
667 silc_client_conn_auth_continue,
672 case SILC_AUTH_PUBLIC_KEY:
673 if (!ctx->auth_data) {
674 /* Public key authentication */
675 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
679 auth_data = ctx->auth_data;
680 auth_data_len = ctx->auth_data_len;
686 silc_client_conn_auth_continue(auth_data,
687 auth_data_len, protocol);
691 case SILC_PROTOCOL_STATE_END:
694 * End protocol. Nothing special to be done here.
697 /* Protocol has ended, call the final callback */
698 if (protocol->final_callback)
699 silc_protocol_execute_final(protocol, client->schedule);
701 silc_protocol_free(protocol);
705 case SILC_PROTOCOL_STATE_ERROR:
708 * Error. Send notify to remote.
710 unsigned char error[4];
712 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
714 /* Error in protocol. Send FAILURE packet. Although I don't think
715 this could ever happen on client side. */
716 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
717 NULL, 0, NULL, NULL, error, 4, TRUE);
719 /* On error the final callback is always called. */
720 if (protocol->final_callback)
721 silc_protocol_execute_final(protocol, client->schedule);
723 silc_protocol_free(protocol);
726 case SILC_PROTOCOL_STATE_FAILURE:
728 * Received failure from remote.
731 /* On error the final callback is always called. */
732 if (protocol->final_callback)
733 silc_protocol_execute_final(protocol, client->schedule);
735 silc_protocol_free(protocol);
738 case SILC_PROTOCOL_STATE_UNKNOWN:
744 * Re-key protocol routines
747 /* Actually takes the new keys into use. */
750 silc_client_protocol_rekey_validate(SilcClient client,
751 SilcClientRekeyInternalContext *ctx,
752 SilcSocketConnection sock,
753 SilcSKEKeyMaterial *keymat,
756 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
758 if (ctx->responder == TRUE) {
760 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
761 keymat->enc_key_len);
762 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
763 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
764 keymat->hmac_key_len);
766 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
767 keymat->enc_key_len);
768 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
769 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
770 keymat->hmac_key_len);
774 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
775 keymat->enc_key_len);
776 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
777 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
778 keymat->hmac_key_len);
780 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
781 keymat->enc_key_len);
782 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
783 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
784 keymat->hmac_key_len);
788 /* Save the current sending encryption key */
790 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
791 silc_free(conn->rekey->send_enc_key);
792 conn->rekey->send_enc_key =
793 silc_calloc(keymat->enc_key_len / 8,
794 sizeof(*conn->rekey->send_enc_key));
795 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
796 keymat->enc_key_len / 8);
797 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
801 /* This function actually re-generates (when not using PFS) the keys and
802 takes them into use. */
805 silc_client_protocol_rekey_generate(SilcClient client,
806 SilcClientRekeyInternalContext *ctx,
809 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
810 SilcSKEKeyMaterial *keymat;
811 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
812 uint32 hash_len = conn->hash->hash->hash_len;
814 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
815 send ? "sending" : "receiving"));
817 /* Generate the new key */
818 keymat = silc_calloc(1, sizeof(*keymat));
819 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
820 conn->rekey->enc_key_len,
821 16, key_len, hash_len,
824 /* Set the keys into use */
825 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
827 silc_ske_free_key_material(keymat);
830 /* This function actually re-generates (with PFS) the keys and
831 takes them into use. */
834 silc_client_protocol_rekey_generate_pfs(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;
842 unsigned char *tmpbuf;
845 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
846 send ? "sending" : "receiving"));
848 /* Encode KEY to binary data */
849 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
851 /* Generate the new key */
852 keymat = silc_calloc(1, sizeof(*keymat));
853 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
856 /* Set the keys into use */
857 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
859 memset(tmpbuf, 0, klen);
861 silc_ske_free_key_material(keymat);
864 /* Packet sending callback. This function is provided as packet sending
865 routine to the Key Exchange functions. */
868 silc_client_protocol_rekey_send_packet(SilcSKE ske,
873 SilcProtocol protocol = (SilcProtocol)context;
874 SilcClientRekeyInternalContext *ctx =
875 (SilcClientRekeyInternalContext *)protocol->context;
876 SilcClient client = (SilcClient)ctx->client;
878 /* Send the packet immediately */
879 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
880 packet->data, packet->len, FALSE);
883 /* Performs re-key as defined in the SILC protocol specification. */
885 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
887 SilcProtocol protocol = (SilcProtocol)context;
888 SilcClientRekeyInternalContext *ctx =
889 (SilcClientRekeyInternalContext *)protocol->context;
890 SilcClient client = (SilcClient)ctx->client;
891 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
892 SilcSKEStatus status;
894 SILC_LOG_DEBUG(("Start"));
896 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
897 protocol->state = SILC_PROTOCOL_STATE_START;
899 SILC_LOG_DEBUG(("State=%d", protocol->state));
901 switch(protocol->state) {
902 case SILC_PROTOCOL_STATE_START:
908 if (ctx->responder == TRUE) {
910 * We are receiving party
913 if (ctx->pfs == TRUE) {
915 * Use Perfect Forward Secrecy, ie. negotiate the key material
916 * using the SKE protocol.
919 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
920 /* Error in protocol */
921 protocol->state = SILC_PROTOCOL_STATE_ERROR;
922 silc_protocol_execute(protocol, client->schedule, 0, 300000);
925 ctx->ske = silc_ske_alloc();
926 ctx->ske->rng = client->rng;
927 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
928 silc_ske_group_get_by_number(conn->rekey->ske_group,
929 &ctx->ske->prop->group);
931 silc_ske_set_callbacks(ctx->ske,
932 silc_client_protocol_rekey_send_packet,
933 NULL, NULL, NULL, silc_ske_check_version,
936 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
937 if (status != SILC_SKE_STATUS_OK) {
938 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
941 protocol->state = SILC_PROTOCOL_STATE_ERROR;
942 silc_protocol_execute(protocol, client->schedule, 0, 300000);
946 /* Advance the protocol state */
948 silc_protocol_execute(protocol, client->schedule, 0, 0);
951 * Do normal and simple re-key.
954 /* Send the REKEY_DONE to indicate we will take new keys into use */
955 silc_client_packet_send(client, ctx->sock,
956 SILC_PACKET_REKEY_DONE,
957 NULL, 0, NULL, NULL, NULL, 0, FALSE);
959 /* After we send REKEY_DONE we must set the sending encryption
960 key to the new key since all packets after this packet must
961 encrypted with the new key. */
962 silc_client_protocol_rekey_generate(client, ctx, TRUE);
964 /* The protocol ends in next stage. */
965 protocol->state = SILC_PROTOCOL_STATE_END;
970 * We are the initiator of this protocol
973 /* Start the re-key by sending the REKEY packet */
974 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
975 NULL, 0, NULL, NULL, NULL, 0, FALSE);
977 if (ctx->pfs == TRUE) {
979 * Use Perfect Forward Secrecy, ie. negotiate the key material
980 * using the SKE protocol.
982 ctx->ske = silc_ske_alloc();
983 ctx->ske->rng = client->rng;
984 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
985 silc_ske_group_get_by_number(conn->rekey->ske_group,
986 &ctx->ske->prop->group);
988 silc_ske_set_callbacks(ctx->ske,
989 silc_client_protocol_rekey_send_packet,
990 NULL, NULL, NULL, silc_ske_check_version,
993 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL);
994 if (status != SILC_SKE_STATUS_OK) {
995 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
998 protocol->state = SILC_PROTOCOL_STATE_ERROR;
999 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1003 /* Advance the protocol state */
1007 * Do normal and simple re-key.
1010 /* Send the REKEY_DONE to indicate we will take new keys into use
1012 silc_client_packet_send(client, ctx->sock,
1013 SILC_PACKET_REKEY_DONE,
1014 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1016 /* After we send REKEY_DONE we must set the sending encryption
1017 key to the new key since all packets after this packet must
1018 encrypted with the new key. */
1019 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1021 /* The protocol ends in next stage. */
1022 protocol->state = SILC_PROTOCOL_STATE_END;
1030 * Second state, used only when oding re-key with PFS.
1032 if (ctx->responder == TRUE) {
1033 if (ctx->pfs == TRUE) {
1035 * Send our KE packe to the initiator now that we've processed
1036 * the initiator's KE packet.
1038 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1039 SILC_SKE_PK_TYPE_SILC);
1041 if (status != SILC_SKE_STATUS_OK) {
1042 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1045 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1046 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1052 if (ctx->pfs == TRUE) {
1054 * The packet type must be KE packet
1056 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1057 /* Error in protocol */
1058 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1059 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1062 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1063 if (status != SILC_SKE_STATUS_OK) {
1064 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1067 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1068 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1074 /* Send the REKEY_DONE to indicate we will take new keys into use
1076 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1077 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1079 /* After we send REKEY_DONE we must set the sending encryption
1080 key to the new key since all packets after this packet must
1081 encrypted with the new key. */
1082 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1084 /* The protocol ends in next stage. */
1085 protocol->state = SILC_PROTOCOL_STATE_END;
1088 case SILC_PROTOCOL_STATE_END:
1093 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1094 /* Error in protocol */
1095 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1096 silc_protocol_execute(protocol, client->schedule, 0, 0);
1099 /* We received the REKEY_DONE packet and all packets after this is
1100 encrypted with the new key so set the decryption key to the new key */
1101 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1103 /* Protocol has ended, call the final callback */
1104 if (protocol->final_callback)
1105 silc_protocol_execute_final(protocol, client->schedule);
1107 silc_protocol_free(protocol);
1110 case SILC_PROTOCOL_STATE_ERROR:
1115 if (ctx->pfs == TRUE) {
1116 /* Send abort notification */
1117 silc_ske_abort(ctx->ske, ctx->ske->status);
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_FAILURE:
1129 * We have received failure from remote
1132 /* On error the final callback is always called. */
1133 if (protocol->final_callback)
1134 silc_protocol_execute_final(protocol, client->schedule);
1136 silc_protocol_free(protocol);
1139 case SILC_PROTOCOL_STATE_UNKNOWN:
1145 /* Registers protocols used in client */
1147 void silc_client_protocols_register(void)
1149 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1150 silc_client_protocol_connection_auth);
1151 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1152 silc_client_protocol_key_exchange);
1153 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1154 silc_client_protocol_rekey);
1157 /* Unregisters protocols */
1159 void silc_client_protocols_unregister(void)
1161 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1162 silc_client_protocol_connection_auth);
1163 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1164 silc_client_protocol_key_exchange);
1165 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1166 silc_client_protocol_rekey);