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,
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->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->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
223 "We don't support server version `%s'", version);
228 /* Callback that is called by the SKE to indicate that it is safe to
229 continue the execution of the protocol. Is given as argument to the
230 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
231 This is called due to the fact that the public key verification
232 process is asynchronous and we must not continue the protocl until
233 the public key has been verified and this callback is called. */
235 static void silc_client_protocol_ke_continue(SilcSKE ske,
238 SilcProtocol protocol = (SilcProtocol)context;
239 SilcClientKEInternalContext *ctx =
240 (SilcClientKEInternalContext *)protocol->context;
241 SilcClient client = (SilcClient)ctx->client;
242 SilcClientConnection conn = ctx->sock->user_data;
244 SILC_LOG_DEBUG(("Start"));
246 if (ske->status != SILC_SKE_STATUS_OK) {
247 /* Call failure client operation */
248 client->ops->failure(client, conn, protocol, (void *)ske->status);
249 protocol->state = SILC_PROTOCOL_STATE_ERROR;
250 silc_protocol_execute(protocol, client->schedule, 0, 0);
254 /* Send Ok to the other end. We will end the protocol as server
255 sends Ok to us when we will take the new keys into use. Do this
256 if we are initiator. This is happens when this callback was sent
257 to silc_ske_initiator_finish function. */
258 if (ctx->responder == FALSE) {
259 silc_ske_end(ctx->ske);
261 /* End the protocol on the next round */
262 protocol->state = SILC_PROTOCOL_STATE_END;
265 /* Advance protocol state and call the next state if we are responder.
266 This happens when this callback was sent to silc_ske_responder_phase_2
268 if (ctx->responder == TRUE) {
270 silc_protocol_execute(protocol, client->schedule, 0, 100000);
274 /* Performs key exchange protocol. This is used for both initiator
275 and responder key exchange. This may be called recursively. */
277 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
279 SilcProtocol protocol = (SilcProtocol)context;
280 SilcClientKEInternalContext *ctx =
281 (SilcClientKEInternalContext *)protocol->context;
282 SilcClient client = (SilcClient)ctx->client;
283 SilcClientConnection conn = ctx->sock->user_data;
284 SilcSKEStatus status = SILC_SKE_STATUS_OK;
286 SILC_LOG_DEBUG(("Start"));
288 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
289 protocol->state = SILC_PROTOCOL_STATE_START;
291 switch(protocol->state) {
292 case SILC_PROTOCOL_STATE_START:
299 /* Allocate Key Exchange object */
300 ske = silc_ske_alloc();
302 ske->rng = client->rng;
303 ske->user_data = (void *)client;
305 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
307 silc_client_protocol_ke_continue,
308 silc_ske_check_version,
311 if (ctx->responder == TRUE) {
312 /* Start the key exchange by processing the received security
313 properties packet from initiator. */
314 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
315 client->silc_client_version,
316 ctx->packet->buffer, TRUE);
318 SilcSKEStartPayload *start_payload;
320 /* Assemble security properties. */
321 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_MUTUAL,
322 client->silc_client_version,
325 /* Start the key exchange by sending our security properties
326 to the remote end. */
327 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
331 /* Return now if the procedure is pending */
332 if (status == SILC_SKE_STATUS_PENDING)
335 if (status != SILC_SKE_STATUS_OK) {
336 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
338 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
341 protocol->state = SILC_PROTOCOL_STATE_ERROR;
342 silc_protocol_execute(protocol, client->schedule, 0, 0);
346 /* Advance protocol state and call the next state if we are responder */
348 if (ctx->responder == TRUE)
349 silc_protocol_execute(protocol, client->schedule, 0, 100000);
357 if (ctx->responder == TRUE) {
358 /* Sends the selected security properties to the initiator. */
360 silc_ske_responder_phase_1(ctx->ske,
361 ctx->ske->start_payload);
363 /* Call Phase-1 function. This processes the Key Exchange Start
364 paylaod reply we just got from the responder. The callback
365 function will receive the processed payload where we will
367 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
370 if (status != SILC_SKE_STATUS_OK) {
371 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
373 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
376 protocol->state = SILC_PROTOCOL_STATE_ERROR;
377 silc_protocol_execute(protocol, client->schedule, 0, 0);
381 /* Advance protocol state and call next state if we are initiator */
383 if (ctx->responder == FALSE)
384 silc_protocol_execute(protocol, client->schedule, 0, 100000);
392 if (ctx->responder == TRUE) {
393 /* Process the received Key Exchange 1 Payload packet from
394 the initiator. This also creates our parts of the Diffie
395 Hellman algorithm. The silc_client_protocol_ke_continue will
396 be called after the public key has been verified. */
397 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
399 /* Call the Phase-2 function. This creates Diffie Hellman
400 key exchange parameters and sends our public part inside
401 Key Exhange 1 Payload to the responder. */
402 status = silc_ske_initiator_phase_2(ctx->ske,
404 client->private_key);
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->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
453 "Received unsupported server %s public key",
454 ctx->sock->hostname);
456 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
457 "Error during key exchange protocol with server %s",
458 ctx->sock->hostname);
460 protocol->state = SILC_PROTOCOL_STATE_ERROR;
461 silc_protocol_execute(protocol, client->schedule, 0, 0);
467 case SILC_PROTOCOL_STATE_END:
472 SilcSKEKeyMaterial *keymat;
473 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
474 int hash_len = ctx->ske->prop->hash->hash->hash_len;
476 /* Process the key material */
477 keymat = silc_calloc(1, sizeof(*keymat));
478 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
480 if (status != SILC_SKE_STATUS_OK) {
481 protocol->state = SILC_PROTOCOL_STATE_ERROR;
482 silc_protocol_execute(protocol, client->schedule, 0, 300000);
483 silc_ske_free_key_material(keymat);
486 ctx->keymat = keymat;
488 /* Send Ok to the other end if we are responder. If we are initiator
489 we have sent this already. */
490 if (ctx->responder == TRUE)
491 silc_ske_end(ctx->ske);
493 /* Unregister the timeout task since the protocol has ended.
494 This was the timeout task to be executed if the protocol is
495 not completed fast enough. */
496 if (ctx->timeout_task)
497 silc_schedule_task_del(client->schedule, ctx->timeout_task);
499 /* Protocol has ended, call the final callback */
500 if (protocol->final_callback)
501 silc_protocol_execute_final(protocol, client->schedule);
503 silc_protocol_free(protocol);
507 case SILC_PROTOCOL_STATE_ERROR:
509 * Error during protocol
512 /* Send abort notification */
513 silc_ske_abort(ctx->ske, ctx->ske->status);
515 /* On error the final callback is always called. */
516 if (protocol->final_callback)
517 silc_protocol_execute_final(protocol, client->schedule);
519 silc_protocol_free(protocol);
522 case SILC_PROTOCOL_STATE_FAILURE:
524 * Received failure from remote.
527 /* Unregister the timeout task since the protocol has ended.
528 This was the timeout task to be executed if the protocol is
529 not completed fast enough. */
530 if (ctx->timeout_task)
531 silc_schedule_task_del(client->schedule, ctx->timeout_task);
533 /* On error the final callback is always called. */
534 if (protocol->final_callback)
535 silc_protocol_execute_final(protocol, client->schedule);
537 silc_protocol_free(protocol);
539 case SILC_PROTOCOL_STATE_UNKNOWN:
545 * Connection Authentication protocol functions
549 silc_client_get_public_key_auth(SilcClient client,
550 SilcClientConnection conn,
551 unsigned char *auth_data,
552 uint32 *auth_data_len,
559 /* Use our default key */
562 /* Make the authentication data. Protocol says it is HASH plus
564 len = ske->hash_len + ske->start_payload_copy->len;
565 auth = silc_buffer_alloc(len);
566 silc_buffer_pull_tail(auth, len);
567 silc_buffer_format(auth,
568 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
569 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
570 ske->start_payload_copy->len),
573 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
574 auth->len, auth_data, auth_data_len)) {
575 silc_buffer_free(auth);
579 silc_buffer_free(auth);
583 /* Continues the connection authentication protocol. This funtion may
584 be called directly or used as SilcAskPassphrase callback. */
587 silc_client_conn_auth_continue(unsigned char *auth_data,
588 uint32 auth_data_len, void *context)
590 SilcProtocol protocol = (SilcProtocol)context;
591 SilcClientConnAuthInternalContext *ctx =
592 (SilcClientConnAuthInternalContext *)protocol->context;
593 SilcClient client = (SilcClient)ctx->client;
597 SILC_LOG_DEBUG(("Start"));
599 payload_len = 4 + auth_data_len;
600 packet = silc_buffer_alloc(payload_len);
601 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
602 silc_buffer_format(packet,
603 SILC_STR_UI_SHORT(payload_len),
604 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
605 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
608 /* Send the packet to server */
609 silc_client_packet_send(client, ctx->sock,
610 SILC_PACKET_CONNECTION_AUTH,
612 packet->data, packet->len, TRUE);
613 silc_buffer_free(packet);
615 /* Next state is end of protocol */
616 protocol->state = SILC_PROTOCOL_STATE_END;
619 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
621 SilcProtocol protocol = (SilcProtocol)context;
622 SilcClientConnAuthInternalContext *ctx =
623 (SilcClientConnAuthInternalContext *)protocol->context;
624 SilcClient client = (SilcClient)ctx->client;
625 SilcClientConnection conn = ctx->sock->user_data;
627 SILC_LOG_DEBUG(("Start"));
629 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
630 protocol->state = SILC_PROTOCOL_STATE_START;
632 switch(protocol->state) {
633 case SILC_PROTOCOL_STATE_START:
636 * Start protocol. We send authentication data to the server
637 * to be authenticated.
639 unsigned char *auth_data = NULL;
640 uint32 auth_data_len = 0;
641 unsigned char sign[1024];
643 switch(ctx->auth_meth) {
645 /* No authentication required */
648 case SILC_AUTH_PASSWORD:
649 /* Password authentication */
650 if (ctx->auth_data && ctx->auth_data_len) {
651 auth_data = ctx->auth_data;
652 auth_data_len = ctx->auth_data_len;
656 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO,
657 "Password authentication required by server %s",
658 ctx->sock->hostname);
659 client->ops->ask_passphrase(client, conn,
660 silc_client_conn_auth_continue,
665 case SILC_AUTH_PUBLIC_KEY:
666 if (!ctx->auth_data) {
667 /* Public key authentication */
668 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
672 auth_data = ctx->auth_data;
673 auth_data_len = ctx->auth_data_len;
679 silc_client_conn_auth_continue(auth_data,
680 auth_data_len, protocol);
684 case SILC_PROTOCOL_STATE_END:
687 * End protocol. Nothing special to be done here.
690 /* Protocol has ended, call the final callback */
691 if (protocol->final_callback)
692 silc_protocol_execute_final(protocol, client->schedule);
694 silc_protocol_free(protocol);
698 case SILC_PROTOCOL_STATE_ERROR:
701 * Error. Send notify to remote.
703 unsigned char error[4];
705 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
707 /* Error in protocol. Send FAILURE packet. Although I don't think
708 this could ever happen on client side. */
709 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
710 NULL, 0, NULL, NULL, error, 4, TRUE);
712 /* On error the final callback is always called. */
713 if (protocol->final_callback)
714 silc_protocol_execute_final(protocol, client->schedule);
716 silc_protocol_free(protocol);
719 case SILC_PROTOCOL_STATE_FAILURE:
721 * Received failure from remote.
724 /* On error the final callback is always called. */
725 if (protocol->final_callback)
726 silc_protocol_execute_final(protocol, client->schedule);
728 silc_protocol_free(protocol);
731 case SILC_PROTOCOL_STATE_UNKNOWN:
737 * Re-key protocol routines
740 /* Actually takes the new keys into use. */
743 silc_client_protocol_rekey_validate(SilcClient client,
744 SilcClientRekeyInternalContext *ctx,
745 SilcSocketConnection sock,
746 SilcSKEKeyMaterial *keymat,
749 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
751 if (ctx->responder == TRUE) {
753 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
754 keymat->enc_key_len);
755 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
756 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
757 keymat->hmac_key_len);
759 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
760 keymat->enc_key_len);
761 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
762 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
763 keymat->hmac_key_len);
767 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
768 keymat->enc_key_len);
769 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
770 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
771 keymat->hmac_key_len);
773 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
774 keymat->enc_key_len);
775 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
776 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
777 keymat->hmac_key_len);
781 /* Save the current sending encryption key */
783 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
784 silc_free(conn->rekey->send_enc_key);
785 conn->rekey->send_enc_key =
786 silc_calloc(keymat->enc_key_len / 8,
787 sizeof(*conn->rekey->send_enc_key));
788 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
789 keymat->enc_key_len / 8);
790 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
794 /* This function actually re-generates (when not using PFS) the keys and
795 takes them into use. */
798 silc_client_protocol_rekey_generate(SilcClient client,
799 SilcClientRekeyInternalContext *ctx,
802 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
803 SilcSKEKeyMaterial *keymat;
804 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
805 uint32 hash_len = conn->hash->hash->hash_len;
807 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
808 send ? "sending" : "receiving"));
810 /* Generate the new key */
811 keymat = silc_calloc(1, sizeof(*keymat));
812 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
813 conn->rekey->enc_key_len,
814 16, key_len, hash_len,
817 /* Set the keys into use */
818 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
820 silc_ske_free_key_material(keymat);
823 /* This function actually re-generates (with PFS) the keys and
824 takes them into use. */
827 silc_client_protocol_rekey_generate_pfs(SilcClient client,
828 SilcClientRekeyInternalContext *ctx,
831 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
832 SilcSKEKeyMaterial *keymat;
833 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
834 uint32 hash_len = conn->hash->hash->hash_len;
835 unsigned char *tmpbuf;
838 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
839 send ? "sending" : "receiving"));
841 /* Encode KEY to binary data */
842 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
844 /* Generate the new key */
845 keymat = silc_calloc(1, sizeof(*keymat));
846 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
849 /* Set the keys into use */
850 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
852 memset(tmpbuf, 0, klen);
854 silc_ske_free_key_material(keymat);
857 /* Packet sending callback. This function is provided as packet sending
858 routine to the Key Exchange functions. */
861 silc_client_protocol_rekey_send_packet(SilcSKE ske,
866 SilcProtocol protocol = (SilcProtocol)context;
867 SilcClientRekeyInternalContext *ctx =
868 (SilcClientRekeyInternalContext *)protocol->context;
869 SilcClient client = (SilcClient)ctx->client;
871 /* Send the packet immediately */
872 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
873 packet->data, packet->len, FALSE);
876 /* Performs re-key as defined in the SILC protocol specification. */
878 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
880 SilcProtocol protocol = (SilcProtocol)context;
881 SilcClientRekeyInternalContext *ctx =
882 (SilcClientRekeyInternalContext *)protocol->context;
883 SilcClient client = (SilcClient)ctx->client;
884 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
885 SilcSKEStatus status;
887 SILC_LOG_DEBUG(("Start"));
889 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
890 protocol->state = SILC_PROTOCOL_STATE_START;
892 SILC_LOG_DEBUG(("State=%d", protocol->state));
894 switch(protocol->state) {
895 case SILC_PROTOCOL_STATE_START:
901 if (ctx->responder == TRUE) {
903 * We are receiving party
906 if (ctx->pfs == TRUE) {
908 * Use Perfect Forward Secrecy, ie. negotiate the key material
909 * using the SKE protocol.
912 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
913 /* Error in protocol */
914 protocol->state = SILC_PROTOCOL_STATE_ERROR;
915 silc_protocol_execute(protocol, client->schedule, 0, 300000);
918 ctx->ske = silc_ske_alloc();
919 ctx->ske->rng = client->rng;
920 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
921 silc_ske_get_group_by_number(conn->rekey->ske_group,
922 &ctx->ske->prop->group);
924 silc_ske_set_callbacks(ctx->ske,
925 silc_client_protocol_rekey_send_packet,
926 NULL, NULL, NULL, silc_ske_check_version,
929 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
930 if (status != SILC_SKE_STATUS_OK) {
931 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
934 protocol->state = SILC_PROTOCOL_STATE_ERROR;
935 silc_protocol_execute(protocol, client->schedule, 0, 300000);
939 /* Advance the protocol state */
941 silc_protocol_execute(protocol, client->schedule, 0, 0);
944 * Do normal and simple re-key.
947 /* Send the REKEY_DONE to indicate we will take new keys into use */
948 silc_client_packet_send(client, ctx->sock,
949 SILC_PACKET_REKEY_DONE,
950 NULL, 0, NULL, NULL, NULL, 0, FALSE);
952 /* After we send REKEY_DONE we must set the sending encryption
953 key to the new key since all packets after this packet must
954 encrypted with the new key. */
955 silc_client_protocol_rekey_generate(client, ctx, TRUE);
957 /* The protocol ends in next stage. */
958 protocol->state = SILC_PROTOCOL_STATE_END;
963 * We are the initiator of this protocol
966 /* Start the re-key by sending the REKEY packet */
967 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
968 NULL, 0, NULL, NULL, NULL, 0, FALSE);
970 if (ctx->pfs == TRUE) {
972 * Use Perfect Forward Secrecy, ie. negotiate the key material
973 * using the SKE protocol.
975 ctx->ske = silc_ske_alloc();
976 ctx->ske->rng = client->rng;
977 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
978 silc_ske_get_group_by_number(conn->rekey->ske_group,
979 &ctx->ske->prop->group);
981 silc_ske_set_callbacks(ctx->ske,
982 silc_client_protocol_rekey_send_packet,
983 NULL, NULL, NULL, silc_ske_check_version,
986 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL);
987 if (status != SILC_SKE_STATUS_OK) {
988 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
991 protocol->state = SILC_PROTOCOL_STATE_ERROR;
992 silc_protocol_execute(protocol, client->schedule, 0, 300000);
996 /* Advance the protocol state */
1000 * Do normal and simple re-key.
1003 /* Send the REKEY_DONE to indicate we will take new keys into use
1005 silc_client_packet_send(client, ctx->sock,
1006 SILC_PACKET_REKEY_DONE,
1007 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1009 /* After we send REKEY_DONE we must set the sending encryption
1010 key to the new key since all packets after this packet must
1011 encrypted with the new key. */
1012 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1014 /* The protocol ends in next stage. */
1015 protocol->state = SILC_PROTOCOL_STATE_END;
1023 * Second state, used only when oding re-key with PFS.
1025 if (ctx->responder == TRUE) {
1026 if (ctx->pfs == TRUE) {
1028 * Send our KE packe to the initiator now that we've processed
1029 * the initiator's KE packet.
1031 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1032 SILC_SKE_PK_TYPE_SILC);
1034 if (status != SILC_SKE_STATUS_OK) {
1035 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1038 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1039 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1045 if (ctx->pfs == TRUE) {
1047 * The packet type must be KE packet
1049 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1050 /* Error in protocol */
1051 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1052 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1055 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1056 if (status != SILC_SKE_STATUS_OK) {
1057 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1060 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1061 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1067 /* Send the REKEY_DONE to indicate we will take new keys into use
1069 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1070 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1072 /* After we send REKEY_DONE we must set the sending encryption
1073 key to the new key since all packets after this packet must
1074 encrypted with the new key. */
1075 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1077 /* The protocol ends in next stage. */
1078 protocol->state = SILC_PROTOCOL_STATE_END;
1081 case SILC_PROTOCOL_STATE_END:
1086 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1087 /* Error in protocol */
1088 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1089 silc_protocol_execute(protocol, client->schedule, 0, 0);
1092 /* We received the REKEY_DONE packet and all packets after this is
1093 encrypted with the new key so set the decryption key to the new key */
1094 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1096 /* Protocol has ended, call the final callback */
1097 if (protocol->final_callback)
1098 silc_protocol_execute_final(protocol, client->schedule);
1100 silc_protocol_free(protocol);
1103 case SILC_PROTOCOL_STATE_ERROR:
1108 if (ctx->pfs == TRUE) {
1109 /* Send abort notification */
1110 silc_ske_abort(ctx->ske, ctx->ske->status);
1113 /* On error the final callback is always called. */
1114 if (protocol->final_callback)
1115 silc_protocol_execute_final(protocol, client->schedule);
1117 silc_protocol_free(protocol);
1120 case SILC_PROTOCOL_STATE_FAILURE:
1122 * We have received failure from remote
1125 /* On error the final callback is always called. */
1126 if (protocol->final_callback)
1127 silc_protocol_execute_final(protocol, client->schedule);
1129 silc_protocol_free(protocol);
1132 case SILC_PROTOCOL_STATE_UNKNOWN:
1138 /* Registers protocols used in client */
1140 void silc_client_protocols_register(void)
1142 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1143 silc_client_protocol_connection_auth);
1144 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1145 silc_client_protocol_key_exchange);
1146 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1147 silc_client_protocol_rekey);
1150 /* Unregisters protocols */
1152 void silc_client_protocols_unregister(void)
1154 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1155 silc_client_protocol_connection_auth);
1156 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1157 silc_client_protocol_key_exchange);
1158 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1159 silc_client_protocol_rekey);