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->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)
117 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
119 SILC_LOG_DEBUG(("Setting new keys into use"));
121 /* Allocate cipher to be used in the communication */
122 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
123 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
124 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
125 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
127 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
128 keymat->enc_key_len);
129 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
130 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
131 keymat->enc_key_len);
132 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
133 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
134 keymat->hmac_key_len);
135 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
136 keymat->hmac_key_len);
139 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
140 conn->rekey->send_enc_key =
141 silc_calloc(keymat->enc_key_len / 8,
142 sizeof(*conn->rekey->send_enc_key));
143 memcpy(conn->rekey->send_enc_key,
144 keymat->send_enc_key, keymat->enc_key_len / 8);
145 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
147 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
148 conn->rekey->pfs = TRUE;
149 conn->rekey->ske_group = silc_ske_group_get_number(group);
151 /* Save the HASH function */
152 silc_hash_alloc(hash->hash->name, &conn->hash);
155 /* Checks the version string of the server. */
157 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
158 uint32 len, void *context)
160 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
161 SilcClient client = (SilcClient)ske->user_data;
162 SilcSKEStatus status = SILC_SKE_STATUS_OK;
164 int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
166 /* Check for initial version string */
167 if (!strstr(version, "SILC-1.0-"))
168 status = SILC_SKE_STATUS_BAD_VERSION;
170 /* Check software version */
174 status = SILC_SKE_STATUS_BAD_VERSION;
177 cp = strchr(cp, '.');
182 cp = strchr(cp, '.');
184 build = atoi(cp + 1);
186 cp = client->silc_client_version + 9;
188 status = SILC_SKE_STATUS_BAD_VERSION;
191 cp = strchr(cp, '.');
196 cp = strchr(cp, '.');
198 build2 = atoi(cp + 1);
201 status = SILC_SKE_STATUS_BAD_VERSION;
203 status = SILC_SKE_STATUS_BAD_VERSION;
205 if (status != SILC_SKE_STATUS_OK)
206 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
207 "We don't support server version `%s'", version);
212 /* Callback that is called by the SKE to indicate that it is safe to
213 continue the execution of the protocol. Is given as argument to the
214 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
215 This is called due to the fact that the public key verification
216 process is asynchronous and we must not continue the protocl until
217 the public key has been verified and this callback is called. */
219 static void silc_client_protocol_ke_continue(SilcSKE ske,
222 SilcProtocol protocol = (SilcProtocol)context;
223 SilcClientKEInternalContext *ctx =
224 (SilcClientKEInternalContext *)protocol->context;
225 SilcClient client = (SilcClient)ctx->client;
226 SilcClientConnection conn = ctx->sock->user_data;
228 SILC_LOG_DEBUG(("Start"));
230 if (ske->status != SILC_SKE_STATUS_OK) {
231 if (ske->status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
232 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
233 "Received unsupported server %s public key",
234 ctx->sock->hostname);
235 } else if (ske->status == SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED) {
236 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
237 "Remote host did not send its public key, even though "
240 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
241 "Error during key exchange protocol with server %s",
242 ctx->sock->hostname);
245 protocol->state = SILC_PROTOCOL_STATE_ERROR;
246 silc_protocol_execute(protocol, client->schedule, 0, 0);
250 /* Send Ok to the other end. We will end the protocol as server
251 sends Ok to us when we will take the new keys into use. Do this
252 if we are initiator. This is happens when this callback was sent
253 to silc_ske_initiator_finish function. */
254 if (ctx->responder == FALSE) {
255 silc_ske_end(ctx->ske);
257 /* End the protocol on the next round */
258 protocol->state = SILC_PROTOCOL_STATE_END;
261 /* Advance protocol state and call the next state if we are responder.
262 This happens when this callback was sent to silc_ske_responder_phase_2
264 if (ctx->responder == TRUE) {
266 silc_protocol_execute(protocol, client->schedule, 0, 100000);
270 /* Performs key exchange protocol. This is used for both initiator
271 and responder key exchange. This may be called recursively. */
273 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
275 SilcProtocol protocol = (SilcProtocol)context;
276 SilcClientKEInternalContext *ctx =
277 (SilcClientKEInternalContext *)protocol->context;
278 SilcClient client = (SilcClient)ctx->client;
279 SilcClientConnection conn = ctx->sock->user_data;
280 SilcSKEStatus status = SILC_SKE_STATUS_OK;
282 SILC_LOG_DEBUG(("Start"));
284 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
285 protocol->state = SILC_PROTOCOL_STATE_START;
287 switch(protocol->state) {
288 case SILC_PROTOCOL_STATE_START:
295 /* Allocate Key Exchange object */
296 ske = silc_ske_alloc();
298 ske->rng = client->rng;
299 ske->user_data = (void *)client;
301 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
303 silc_client_protocol_ke_continue,
304 silc_ske_check_version,
307 if (ctx->responder == TRUE) {
308 /* Start the key exchange by processing the received security
309 properties packet from initiator. */
310 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
311 client->silc_client_version,
312 ctx->packet->buffer, TRUE);
314 SilcSKEStartPayload *start_payload;
316 /* Assemble security properties. */
317 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
318 client->silc_client_version,
321 /* Start the key exchange by sending our security properties
322 to the remote end. */
323 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
327 /* Return now if the procedure is pending */
328 if (status == SILC_SKE_STATUS_PENDING)
331 if (status != SILC_SKE_STATUS_OK) {
332 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
334 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
337 protocol->state = SILC_PROTOCOL_STATE_ERROR;
338 silc_protocol_execute(protocol, client->schedule, 0, 0);
342 /* Advance protocol state and call the next state if we are responder */
344 if (ctx->responder == TRUE)
345 silc_protocol_execute(protocol, client->schedule, 0, 100000);
353 if (ctx->responder == TRUE) {
354 /* Sends the selected security properties to the initiator. */
356 silc_ske_responder_phase_1(ctx->ske,
357 ctx->ske->start_payload);
359 /* Call Phase-1 function. This processes the Key Exchange Start
360 paylaod reply we just got from the responder. The callback
361 function will receive the processed payload where we will
363 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
366 if (status != SILC_SKE_STATUS_OK) {
367 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
369 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
372 protocol->state = SILC_PROTOCOL_STATE_ERROR;
373 silc_protocol_execute(protocol, client->schedule, 0, 0);
377 /* Advance protocol state and call next state if we are initiator */
379 if (ctx->responder == FALSE)
380 silc_protocol_execute(protocol, client->schedule, 0, 100000);
388 if (ctx->responder == TRUE) {
389 /* Process the received Key Exchange 1 Payload packet from
390 the initiator. This also creates our parts of the Diffie
391 Hellman algorithm. The silc_client_protocol_ke_continue will
392 be called after the public key has been verified. */
393 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
395 /* Call the Phase-2 function. This creates Diffie Hellman
396 key exchange parameters and sends our public part inside
397 Key Exhange 1 Payload to the responder. */
398 status = silc_ske_initiator_phase_2(ctx->ske,
400 client->private_key);
404 /* Return now if the procedure is pending */
405 if (status == SILC_SKE_STATUS_PENDING)
408 if (status != SILC_SKE_STATUS_OK) {
409 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
411 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
414 protocol->state = SILC_PROTOCOL_STATE_ERROR;
415 silc_protocol_execute(protocol, client->schedule, 0, 0);
425 if (ctx->responder == TRUE) {
426 /* This creates the key exchange material and sends our
427 public parts to the initiator inside Key Exchange 2 Payload. */
429 silc_ske_responder_finish(ctx->ske,
430 client->public_key, client->private_key,
431 SILC_SKE_PK_TYPE_SILC);
433 /* End the protocol on the next round */
434 protocol->state = SILC_PROTOCOL_STATE_END;
436 /* Finish the protocol. This verifies the Key Exchange 2 payload
437 sent by responder. The silc_client_protocol_ke_continue will
438 be called after the public key has been verified. */
439 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
442 /* Return now if the procedure is pending */
443 if (status == SILC_SKE_STATUS_PENDING)
446 if (status != SILC_SKE_STATUS_OK) {
447 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
448 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
449 "Received unsupported server %s public key",
450 ctx->sock->hostname);
452 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
453 "Error during key exchange protocol with server %s",
454 ctx->sock->hostname);
456 protocol->state = SILC_PROTOCOL_STATE_ERROR;
457 silc_protocol_execute(protocol, client->schedule, 0, 0);
463 case SILC_PROTOCOL_STATE_END:
468 SilcSKEKeyMaterial *keymat;
469 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
470 int hash_len = ctx->ske->prop->hash->hash->hash_len;
472 /* Process the key material */
473 keymat = silc_calloc(1, sizeof(*keymat));
474 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
476 if (status != SILC_SKE_STATUS_OK) {
477 protocol->state = SILC_PROTOCOL_STATE_ERROR;
478 silc_protocol_execute(protocol, client->schedule, 0, 300000);
479 silc_ske_free_key_material(keymat);
482 ctx->keymat = keymat;
484 /* Send Ok to the other end if we are responder. If we are initiator
485 we have sent this already. */
486 if (ctx->responder == TRUE)
487 silc_ske_end(ctx->ske);
489 /* Unregister the timeout task since the protocol has ended.
490 This was the timeout task to be executed if the protocol is
491 not completed fast enough. */
492 if (ctx->timeout_task)
493 silc_schedule_task_del(client->schedule, ctx->timeout_task);
495 /* Protocol has ended, call the final callback */
496 if (protocol->final_callback)
497 silc_protocol_execute_final(protocol, client->schedule);
499 silc_protocol_free(protocol);
503 case SILC_PROTOCOL_STATE_ERROR:
505 * Error during protocol
508 /* Send abort notification */
509 silc_ske_abort(ctx->ske, ctx->ske->status);
511 /* On error the final callback is always called. */
512 if (protocol->final_callback)
513 silc_protocol_execute_final(protocol, client->schedule);
515 silc_protocol_free(protocol);
518 case SILC_PROTOCOL_STATE_FAILURE:
520 * Received failure from remote.
523 /* Unregister the timeout task since the protocol has ended.
524 This was the timeout task to be executed if the protocol is
525 not completed fast enough. */
526 if (ctx->timeout_task)
527 silc_schedule_task_del(client->schedule, ctx->timeout_task);
529 /* On error the final callback is always called. */
530 if (protocol->final_callback)
531 silc_protocol_execute_final(protocol, client->schedule);
533 silc_protocol_free(protocol);
535 case SILC_PROTOCOL_STATE_UNKNOWN:
541 * Connection Authentication protocol functions
545 silc_client_get_public_key_auth(SilcClient client,
546 SilcClientConnection conn,
547 unsigned char *auth_data,
548 uint32 *auth_data_len,
555 /* Use our default key */
558 /* Make the authentication data. Protocol says it is HASH plus
560 len = ske->hash_len + ske->start_payload_copy->len;
561 auth = silc_buffer_alloc(len);
562 silc_buffer_pull_tail(auth, len);
563 silc_buffer_format(auth,
564 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
565 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
566 ske->start_payload_copy->len),
569 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
570 auth->len, auth_data, auth_data_len)) {
571 silc_buffer_free(auth);
575 silc_buffer_free(auth);
579 /* Continues the connection authentication protocol. This funtion may
580 be called directly or used as SilcAskPassphrase callback. */
583 silc_client_conn_auth_continue(unsigned char *auth_data,
584 uint32 auth_data_len, void *context)
586 SilcProtocol protocol = (SilcProtocol)context;
587 SilcClientConnAuthInternalContext *ctx =
588 (SilcClientConnAuthInternalContext *)protocol->context;
589 SilcClient client = (SilcClient)ctx->client;
593 SILC_LOG_DEBUG(("Start"));
595 payload_len = 4 + auth_data_len;
596 packet = silc_buffer_alloc(payload_len);
597 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
598 silc_buffer_format(packet,
599 SILC_STR_UI_SHORT(payload_len),
600 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
601 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
604 /* Send the packet to server */
605 silc_client_packet_send(client, ctx->sock,
606 SILC_PACKET_CONNECTION_AUTH,
608 packet->data, packet->len, TRUE);
609 silc_buffer_free(packet);
611 /* Next state is end of protocol */
612 protocol->state = SILC_PROTOCOL_STATE_END;
615 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
617 SilcProtocol protocol = (SilcProtocol)context;
618 SilcClientConnAuthInternalContext *ctx =
619 (SilcClientConnAuthInternalContext *)protocol->context;
620 SilcClient client = (SilcClient)ctx->client;
621 SilcClientConnection conn = ctx->sock->user_data;
623 SILC_LOG_DEBUG(("Start"));
625 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
626 protocol->state = SILC_PROTOCOL_STATE_START;
628 switch(protocol->state) {
629 case SILC_PROTOCOL_STATE_START:
632 * Start protocol. We send authentication data to the server
633 * to be authenticated.
635 unsigned char *auth_data = NULL;
636 uint32 auth_data_len = 0;
637 unsigned char sign[1024];
639 switch(ctx->auth_meth) {
641 /* No authentication required */
644 case SILC_AUTH_PASSWORD:
645 /* Password authentication */
646 if (ctx->auth_data && ctx->auth_data_len) {
647 auth_data = ctx->auth_data;
648 auth_data_len = ctx->auth_data_len;
652 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO,
653 "Password authentication required by server %s",
654 ctx->sock->hostname);
655 client->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->send_key, keymat->receive_enc_key,
750 keymat->enc_key_len);
751 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
752 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
753 keymat->hmac_key_len);
755 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
756 keymat->enc_key_len);
757 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
758 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
759 keymat->hmac_key_len);
763 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
764 keymat->enc_key_len);
765 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
766 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
767 keymat->hmac_key_len);
769 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
770 keymat->enc_key_len);
771 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
772 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
773 keymat->hmac_key_len);
777 /* Save the current sending encryption key */
779 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
780 silc_free(conn->rekey->send_enc_key);
781 conn->rekey->send_enc_key =
782 silc_calloc(keymat->enc_key_len / 8,
783 sizeof(*conn->rekey->send_enc_key));
784 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
785 keymat->enc_key_len / 8);
786 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
790 /* This function actually re-generates (when not using PFS) the keys and
791 takes them into use. */
794 silc_client_protocol_rekey_generate(SilcClient client,
795 SilcClientRekeyInternalContext *ctx,
798 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
799 SilcSKEKeyMaterial *keymat;
800 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
801 uint32 hash_len = conn->hash->hash->hash_len;
803 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
804 send ? "sending" : "receiving"));
806 /* Generate the new key */
807 keymat = silc_calloc(1, sizeof(*keymat));
808 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
809 conn->rekey->enc_key_len,
810 16, key_len, hash_len,
813 /* Set the keys into use */
814 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
816 silc_ske_free_key_material(keymat);
819 /* This function actually re-generates (with PFS) the keys and
820 takes them into use. */
823 silc_client_protocol_rekey_generate_pfs(SilcClient client,
824 SilcClientRekeyInternalContext *ctx,
827 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
828 SilcSKEKeyMaterial *keymat;
829 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
830 uint32 hash_len = conn->hash->hash->hash_len;
831 unsigned char *tmpbuf;
834 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
835 send ? "sending" : "receiving"));
837 /* Encode KEY to binary data */
838 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
840 /* Generate the new key */
841 keymat = silc_calloc(1, sizeof(*keymat));
842 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
845 /* Set the keys into use */
846 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
848 memset(tmpbuf, 0, klen);
850 silc_ske_free_key_material(keymat);
853 /* Packet sending callback. This function is provided as packet sending
854 routine to the Key Exchange functions. */
857 silc_client_protocol_rekey_send_packet(SilcSKE ske,
862 SilcProtocol protocol = (SilcProtocol)context;
863 SilcClientRekeyInternalContext *ctx =
864 (SilcClientRekeyInternalContext *)protocol->context;
865 SilcClient client = (SilcClient)ctx->client;
867 /* Send the packet immediately */
868 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
869 packet->data, packet->len, FALSE);
872 /* Performs re-key as defined in the SILC protocol specification. */
874 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
876 SilcProtocol protocol = (SilcProtocol)context;
877 SilcClientRekeyInternalContext *ctx =
878 (SilcClientRekeyInternalContext *)protocol->context;
879 SilcClient client = (SilcClient)ctx->client;
880 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
881 SilcSKEStatus status;
883 SILC_LOG_DEBUG(("Start"));
885 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
886 protocol->state = SILC_PROTOCOL_STATE_START;
888 SILC_LOG_DEBUG(("State=%d", protocol->state));
890 switch(protocol->state) {
891 case SILC_PROTOCOL_STATE_START:
897 if (ctx->responder == TRUE) {
899 * We are receiving party
902 if (ctx->pfs == TRUE) {
904 * Use Perfect Forward Secrecy, ie. negotiate the key material
905 * using the SKE protocol.
908 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
909 /* Error in protocol */
910 protocol->state = SILC_PROTOCOL_STATE_ERROR;
911 silc_protocol_execute(protocol, client->schedule, 0, 300000);
914 ctx->ske = silc_ske_alloc();
915 ctx->ske->rng = client->rng;
916 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
917 silc_ske_get_group_by_number(conn->rekey->ske_group,
918 &ctx->ske->prop->group);
920 silc_ske_set_callbacks(ctx->ske,
921 silc_client_protocol_rekey_send_packet,
922 NULL, NULL, NULL, silc_ske_check_version,
925 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
926 if (status != SILC_SKE_STATUS_OK) {
927 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
930 protocol->state = SILC_PROTOCOL_STATE_ERROR;
931 silc_protocol_execute(protocol, client->schedule, 0, 300000);
935 /* Advance the protocol state */
937 silc_protocol_execute(protocol, client->schedule, 0, 0);
940 * Do normal and simple re-key.
943 /* Send the REKEY_DONE to indicate we will take new keys into use */
944 silc_client_packet_send(client, ctx->sock,
945 SILC_PACKET_REKEY_DONE,
946 NULL, 0, NULL, NULL, NULL, 0, FALSE);
948 /* After we send REKEY_DONE we must set the sending encryption
949 key to the new key since all packets after this packet must
950 encrypted with the new key. */
951 silc_client_protocol_rekey_generate(client, ctx, TRUE);
953 /* The protocol ends in next stage. */
954 protocol->state = SILC_PROTOCOL_STATE_END;
959 * We are the initiator of this protocol
962 /* Start the re-key by sending the REKEY packet */
963 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
964 NULL, 0, NULL, NULL, NULL, 0, FALSE);
966 if (ctx->pfs == TRUE) {
968 * Use Perfect Forward Secrecy, ie. negotiate the key material
969 * using the SKE protocol.
971 ctx->ske = silc_ske_alloc();
972 ctx->ske->rng = client->rng;
973 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
974 silc_ske_get_group_by_number(conn->rekey->ske_group,
975 &ctx->ske->prop->group);
977 silc_ske_set_callbacks(ctx->ske,
978 silc_client_protocol_rekey_send_packet,
979 NULL, NULL, NULL, silc_ske_check_version,
982 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL);
983 if (status != SILC_SKE_STATUS_OK) {
984 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
987 protocol->state = SILC_PROTOCOL_STATE_ERROR;
988 silc_protocol_execute(protocol, client->schedule, 0, 300000);
992 /* Advance the protocol state */
996 * Do normal and simple re-key.
999 /* Send the REKEY_DONE to indicate we will take new keys into use
1001 silc_client_packet_send(client, ctx->sock,
1002 SILC_PACKET_REKEY_DONE,
1003 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1005 /* After we send REKEY_DONE we must set the sending encryption
1006 key to the new key since all packets after this packet must
1007 encrypted with the new key. */
1008 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1010 /* The protocol ends in next stage. */
1011 protocol->state = SILC_PROTOCOL_STATE_END;
1019 * Second state, used only when oding re-key with PFS.
1021 if (ctx->responder == TRUE) {
1022 if (ctx->pfs == TRUE) {
1024 * Send our KE packe to the initiator now that we've processed
1025 * the initiator's KE packet.
1027 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1028 SILC_SKE_PK_TYPE_SILC);
1030 if (status != SILC_SKE_STATUS_OK) {
1031 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1034 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1035 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1041 if (ctx->pfs == TRUE) {
1043 * The packet type must be KE packet
1045 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1046 /* Error in protocol */
1047 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1048 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1051 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1052 if (status != SILC_SKE_STATUS_OK) {
1053 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1056 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1057 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1063 /* Send the REKEY_DONE to indicate we will take new keys into use
1065 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1066 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1068 /* After we send REKEY_DONE we must set the sending encryption
1069 key to the new key since all packets after this packet must
1070 encrypted with the new key. */
1071 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1073 /* The protocol ends in next stage. */
1074 protocol->state = SILC_PROTOCOL_STATE_END;
1077 case SILC_PROTOCOL_STATE_END:
1082 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1083 /* Error in protocol */
1084 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1085 silc_protocol_execute(protocol, client->schedule, 0, 0);
1088 /* We received the REKEY_DONE packet and all packets after this is
1089 encrypted with the new key so set the decryption key to the new key */
1090 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1092 /* Protocol has ended, call the final callback */
1093 if (protocol->final_callback)
1094 silc_protocol_execute_final(protocol, client->schedule);
1096 silc_protocol_free(protocol);
1099 case SILC_PROTOCOL_STATE_ERROR:
1104 if (ctx->pfs == TRUE) {
1105 /* Send abort notification */
1106 silc_ske_abort(ctx->ske, ctx->ske->status);
1109 /* On error the final callback is always called. */
1110 if (protocol->final_callback)
1111 silc_protocol_execute_final(protocol, client->schedule);
1113 silc_protocol_free(protocol);
1116 case SILC_PROTOCOL_STATE_FAILURE:
1118 * We have received failure from remote
1121 /* On error the final callback is always called. */
1122 if (protocol->final_callback)
1123 silc_protocol_execute_final(protocol, client->schedule);
1125 silc_protocol_free(protocol);
1128 case SILC_PROTOCOL_STATE_UNKNOWN:
1134 /* Registers protocols used in client */
1136 void silc_client_protocols_register(void)
1138 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1139 silc_client_protocol_connection_auth);
1140 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1141 silc_client_protocol_key_exchange);
1142 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1143 silc_client_protocol_rekey);
1146 /* Unregisters protocols */
1148 void silc_client_protocols_unregister(void)
1150 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1151 silc_client_protocol_connection_auth);
1152 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1153 silc_client_protocol_key_exchange);
1154 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1155 silc_client_protocol_rekey);