5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Client side of the protocols.
25 #include "silcincludes.h"
26 #include "silcclient.h"
27 #include "client_internal.h"
29 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
30 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
31 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
34 * Key Exhange protocol functions
37 /* Function that is called when SKE protocol sends packets to network. */
39 void silc_client_protocol_ke_send_packet(SilcSKE ske,
44 SilcProtocol protocol = (SilcProtocol)context;
45 SilcClientKEInternalContext *ctx =
46 (SilcClientKEInternalContext *)protocol->context;
47 SilcClient client = (SilcClient)ctx->client;
49 /* Send the packet immediately */
50 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
51 packet->data, packet->len, TRUE);
54 /* Public key verification callback. Called by the application. */
58 SilcSKEVerifyCbCompletion completion;
59 void *completion_context;
62 static void silc_client_verify_key_cb(bool success, void *context)
64 VerifyKeyContext verify = (VerifyKeyContext)context;
66 SILC_LOG_DEBUG(("Start"));
68 /* Call the completion callback back to the SKE */
69 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
70 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
71 verify->completion_context);
76 /* Callback that is called when we have received KE payload from
77 responder. We try to verify the public key now. */
79 void silc_client_protocol_ke_verify_key(SilcSKE ske,
80 unsigned char *pk_data,
82 SilcSKEPKType pk_type,
84 SilcSKEVerifyCbCompletion completion,
85 void *completion_context)
87 SilcProtocol protocol = (SilcProtocol)context;
88 SilcClientKEInternalContext *ctx =
89 (SilcClientKEInternalContext *)protocol->context;
90 SilcClient client = (SilcClient)ctx->client;
91 VerifyKeyContext verify;
93 SILC_LOG_DEBUG(("Start"));
95 verify = silc_calloc(1, sizeof(*verify));
97 verify->completion = completion;
98 verify->completion_context = completion_context;
100 /* Verify public key from user. */
101 client->internal->ops->verify_public_key(client, ctx->sock->user_data,
103 pk_data, pk_len, pk_type,
104 silc_client_verify_key_cb, verify);
107 /* Sets the negotiated key material into use for particular connection. */
109 void silc_client_protocol_ke_set_keys(SilcSKE ske,
110 SilcSocketConnection sock,
111 SilcSKEKeyMaterial *keymat,
116 SilcSKEDiffieHellmanGroup group,
119 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
121 SILC_LOG_DEBUG(("Setting new keys into use"));
123 /* Allocate cipher to be used in the communication */
124 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
125 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
126 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
127 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
129 if (is_responder == TRUE) {
130 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
131 keymat->enc_key_len);
132 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
133 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
134 keymat->enc_key_len);
135 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
136 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
137 keymat->hmac_key_len);
138 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
139 keymat->hmac_key_len);
141 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
142 keymat->enc_key_len);
143 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
144 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
145 keymat->enc_key_len);
146 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
147 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
148 keymat->hmac_key_len);
149 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
150 keymat->hmac_key_len);
154 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
155 conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
156 keymat->enc_key_len / 8);
157 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
159 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
160 conn->rekey->pfs = TRUE;
161 conn->rekey->ske_group = silc_ske_group_get_number(group);
163 /* Save the HASH function */
164 silc_hash_alloc(silc_hash_get_name(hash), &conn->hash);
167 /* Checks the version string of the server. */
169 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
170 SilcUInt32 len, void *context)
172 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
173 SilcClient client = (SilcClient)ske->user_data;
174 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
176 if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
178 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
179 "We don't support server version `%s'",
181 return SILC_SKE_STATUS_BAD_VERSION;
184 if (!silc_parse_version_string(client->internal->silc_client_version,
185 &l_protocol_version, NULL, NULL,
187 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
188 "We don't support server version `%s'",
190 return SILC_SKE_STATUS_BAD_VERSION;
193 /* If remote is too new, don't connect */
194 if (l_protocol_version < r_protocol_version) {
195 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
196 "We don't support server version `%s'",
198 return SILC_SKE_STATUS_BAD_VERSION;
201 ske->sock->version = r_protocol_version;
203 return SILC_SKE_STATUS_OK;
206 /* Callback that is called by the SKE to indicate that it is safe to
207 continue the execution of the protocol. Is given as argument to the
208 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
209 This is called due to the fact that the public key verification
210 process is asynchronous and we must not continue the protocl until
211 the public key has been verified and this callback is called. */
213 static void silc_client_protocol_ke_continue(SilcSKE ske,
216 SilcProtocol protocol = (SilcProtocol)context;
217 SilcClientKEInternalContext *ctx =
218 (SilcClientKEInternalContext *)protocol->context;
219 SilcClient client = (SilcClient)ctx->client;
220 SilcClientConnection conn = ctx->sock->user_data;
222 SILC_LOG_DEBUG(("Start"));
224 if (ske->status != SILC_SKE_STATUS_OK) {
225 /* Call failure client operation */
226 client->internal->ops->failure(client, conn, protocol,
227 (void *)ske->status);
228 protocol->state = SILC_PROTOCOL_STATE_ERROR;
229 silc_protocol_execute(protocol, client->schedule, 0, 0);
233 /* Send Ok to the other end. We will end the protocol as server
234 sends Ok to us when we will take the new keys into use. Do this
235 if we are initiator. This is happens when this callback was sent
236 to silc_ske_initiator_finish function. */
237 if (ctx->responder == FALSE) {
238 silc_ske_end(ctx->ske);
240 /* End the protocol on the next round */
241 protocol->state = SILC_PROTOCOL_STATE_END;
244 /* Advance protocol state and call the next state if we are responder.
245 This happens when this callback was sent to silc_ske_responder_phase_2
247 if (ctx->responder == TRUE) {
249 silc_protocol_execute(protocol, client->schedule, 0, 100000);
253 /* Performs key exchange protocol. This is used for both initiator
254 and responder key exchange. This may be called recursively. */
256 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
258 SilcProtocol protocol = (SilcProtocol)context;
259 SilcClientKEInternalContext *ctx =
260 (SilcClientKEInternalContext *)protocol->context;
261 SilcClient client = (SilcClient)ctx->client;
262 SilcClientConnection conn = ctx->sock->user_data;
263 SilcSKEStatus status = SILC_SKE_STATUS_OK;
265 SILC_LOG_DEBUG(("Start"));
267 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
268 protocol->state = SILC_PROTOCOL_STATE_START;
270 switch(protocol->state) {
271 case SILC_PROTOCOL_STATE_START:
278 /* Allocate Key Exchange object */
279 ctx->ske = ske = silc_ske_alloc(client->rng, client);
281 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
283 silc_client_protocol_ke_continue,
284 silc_ske_check_version,
287 if (ctx->responder == TRUE) {
288 /* Start the key exchange by processing the received security
289 properties packet from initiator. */
291 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
292 client->internal->silc_client_version,
293 ctx->packet->buffer, TRUE);
295 SilcSKEStartPayload *start_payload;
297 /* Assemble security properties. */
298 silc_ske_assemble_security_properties(
299 ske, SILC_SKE_SP_FLAG_MUTUAL,
300 client->internal->silc_client_version,
303 /* Start the key exchange by sending our security properties
304 to the remote end. */
305 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
309 /* Return now if the procedure is pending */
310 if (status == SILC_SKE_STATUS_PENDING)
313 if (status != SILC_SKE_STATUS_OK) {
314 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
316 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
319 protocol->state = SILC_PROTOCOL_STATE_ERROR;
320 silc_protocol_execute(protocol, client->schedule, 0, 0);
324 /* Advance protocol state and call the next state if we are responder */
326 if (ctx->responder == TRUE)
327 silc_protocol_execute(protocol, client->schedule, 0, 100000);
335 if (ctx->responder == TRUE) {
336 /* Sends the selected security properties to the initiator. */
337 status = silc_ske_responder_phase_1(ctx->ske);
339 /* Call Phase-1 function. This processes the Key Exchange Start
340 paylaod reply we just got from the responder. The callback
341 function will receive the processed payload where we will
343 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
346 if (status != SILC_SKE_STATUS_OK) {
347 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
349 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
352 protocol->state = SILC_PROTOCOL_STATE_ERROR;
353 silc_protocol_execute(protocol, client->schedule, 0, 0);
357 /* Advance protocol state and call next state if we are initiator */
359 if (ctx->responder == FALSE)
360 silc_protocol_execute(protocol, client->schedule, 0, 100000);
368 if (ctx->responder == TRUE) {
369 /* Process the received Key Exchange 1 Payload packet from
370 the initiator. This also creates our parts of the Diffie
371 Hellman algorithm. The silc_client_protocol_ke_continue will
372 be called after the public key has been verified. */
373 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
375 /* Call the Phase-2 function. This creates Diffie Hellman
376 key exchange parameters and sends our public part inside
377 Key Exhange 1 Payload to the responder. */
378 status = silc_ske_initiator_phase_2(ctx->ske,
381 SILC_SKE_PK_TYPE_SILC);
385 /* Return now if the procedure is pending */
386 if (status == SILC_SKE_STATUS_PENDING)
389 if (status != SILC_SKE_STATUS_OK) {
390 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
392 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
395 protocol->state = SILC_PROTOCOL_STATE_ERROR;
396 silc_protocol_execute(protocol, client->schedule, 0, 0);
406 if (ctx->responder == TRUE) {
407 /* This creates the key exchange material and sends our
408 public parts to the initiator inside Key Exchange 2 Payload. */
410 silc_ske_responder_finish(ctx->ske,
411 client->public_key, client->private_key,
412 SILC_SKE_PK_TYPE_SILC);
414 /* End the protocol on the next round */
415 protocol->state = SILC_PROTOCOL_STATE_END;
417 /* Finish the protocol. This verifies the Key Exchange 2 payload
418 sent by responder. The silc_client_protocol_ke_continue will
419 be called after the public key has been verified. */
420 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
423 /* Return now if the procedure is pending */
424 if (status == SILC_SKE_STATUS_PENDING)
427 if (status != SILC_SKE_STATUS_OK) {
428 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
429 client->internal->ops->say(
430 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
431 "Received unsupported server %s public key",
432 ctx->sock->hostname);
434 client->internal->ops->say(
435 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
436 "Error during key exchange protocol with server %s",
437 ctx->sock->hostname);
439 protocol->state = SILC_PROTOCOL_STATE_ERROR;
440 silc_protocol_execute(protocol, client->schedule, 0, 0);
446 case SILC_PROTOCOL_STATE_END:
451 SilcSKEKeyMaterial *keymat;
452 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
453 int hash_len = silc_hash_len(ctx->ske->prop->hash);
455 /* Process the key material */
456 keymat = silc_calloc(1, sizeof(*keymat));
457 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
459 if (status != SILC_SKE_STATUS_OK) {
460 protocol->state = SILC_PROTOCOL_STATE_ERROR;
461 silc_protocol_execute(protocol, client->schedule, 0, 300000);
462 silc_ske_free_key_material(keymat);
465 ctx->keymat = keymat;
467 /* Send Ok to the other end if we are responder. If we are initiator
468 we have sent this already. */
469 if (ctx->responder == TRUE)
470 silc_ske_end(ctx->ske);
472 /* Unregister the timeout task since the protocol has ended.
473 This was the timeout task to be executed if the protocol is
474 not completed fast enough. */
475 if (ctx->timeout_task)
476 silc_schedule_task_del(client->schedule, ctx->timeout_task);
478 /* Protocol has ended, call the final callback */
479 if (protocol->final_callback)
480 silc_protocol_execute_final(protocol, client->schedule);
482 silc_protocol_free(protocol);
486 case SILC_PROTOCOL_STATE_ERROR:
488 * Error during protocol
491 /* Send abort notification */
492 silc_ske_abort(ctx->ske, ctx->ske->status);
494 /* On error the final callback is always called. */
495 if (protocol->final_callback)
496 silc_protocol_execute_final(protocol, client->schedule);
498 silc_protocol_free(protocol);
501 case SILC_PROTOCOL_STATE_FAILURE:
503 * Received failure from remote.
506 /* Unregister the timeout task since the protocol has ended.
507 This was the timeout task to be executed if the protocol is
508 not completed fast enough. */
509 if (ctx->timeout_task)
510 silc_schedule_task_del(client->schedule, ctx->timeout_task);
512 /* On error the final callback is always called. */
513 if (protocol->final_callback)
514 silc_protocol_execute_final(protocol, client->schedule);
516 silc_protocol_free(protocol);
518 case SILC_PROTOCOL_STATE_UNKNOWN:
524 * Connection Authentication protocol functions
528 silc_client_get_public_key_auth(SilcClient client,
529 SilcClientConnection conn,
530 unsigned char *auth_data,
531 SilcUInt32 *auth_data_len,
538 /* Use our default key */
541 /* Make the authentication data. Protocol says it is HASH plus
543 len = ske->hash_len + ske->start_payload_copy->len;
544 auth = silc_buffer_alloc(len);
545 silc_buffer_pull_tail(auth, len);
546 silc_buffer_format(auth,
547 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
548 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
549 ske->start_payload_copy->len),
552 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
553 auth->len, auth_data, auth_data_len)) {
554 silc_buffer_free(auth);
558 silc_buffer_free(auth);
562 /* Continues the connection authentication protocol. This funtion may
563 be called directly or used as SilcAskPassphrase callback. */
566 silc_client_conn_auth_continue(unsigned char *auth_data,
567 SilcUInt32 auth_data_len, void *context)
569 SilcProtocol protocol = (SilcProtocol)context;
570 SilcClientConnAuthInternalContext *ctx =
571 (SilcClientConnAuthInternalContext *)protocol->context;
572 SilcClient client = (SilcClient)ctx->client;
575 unsigned char *autf8 = NULL;
577 SILC_LOG_DEBUG(("Start"));
579 /* Passphrase must be UTF-8 encoded, if it isn't encode it */
580 if (ctx->auth_meth == SILC_AUTH_PASSWORD &&
581 !silc_utf8_valid(auth_data, auth_data_len)) {
582 payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
584 autf8 = silc_calloc(payload_len, sizeof(*autf8));
585 auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
586 SILC_STRING_ASCII, autf8, payload_len);
590 payload_len = 4 + auth_data_len;
591 packet = silc_buffer_alloc(payload_len);
592 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
593 silc_buffer_format(packet,
594 SILC_STR_UI_SHORT(payload_len),
595 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
596 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
599 /* Send the packet to server */
600 silc_client_packet_send(client, ctx->sock,
601 SILC_PACKET_CONNECTION_AUTH,
603 packet->data, packet->len, TRUE);
604 silc_buffer_free(packet);
607 /* Next state is end of protocol */
608 protocol->state = SILC_PROTOCOL_STATE_END;
611 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
613 SilcProtocol protocol = (SilcProtocol)context;
614 SilcClientConnAuthInternalContext *ctx =
615 (SilcClientConnAuthInternalContext *)protocol->context;
616 SilcClient client = (SilcClient)ctx->client;
617 SilcClientConnection conn = ctx->sock->user_data;
619 SILC_LOG_DEBUG(("Start"));
621 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
622 protocol->state = SILC_PROTOCOL_STATE_START;
624 switch(protocol->state) {
625 case SILC_PROTOCOL_STATE_START:
628 * Start protocol. We send authentication data to the server
629 * to be authenticated.
631 unsigned char *auth_data = NULL;
632 SilcUInt32 auth_data_len = 0;
633 unsigned char sign[1024];
635 switch(ctx->auth_meth) {
637 /* No authentication required */
640 case SILC_AUTH_PASSWORD:
641 /* Password authentication */
642 if (ctx->auth_data && ctx->auth_data_len) {
643 auth_data = ctx->auth_data;
644 auth_data_len = ctx->auth_data_len;
648 client->internal->ops->say(
649 client, conn, SILC_CLIENT_MESSAGE_INFO,
650 "Password authentication required by server %s",
651 ctx->sock->hostname);
652 client->internal->ops->ask_passphrase(client, conn,
653 silc_client_conn_auth_continue,
658 case SILC_AUTH_PUBLIC_KEY:
659 if (!ctx->auth_data) {
660 /* Public key authentication */
661 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
665 auth_data = ctx->auth_data;
666 auth_data_len = ctx->auth_data_len;
672 silc_client_conn_auth_continue(auth_data,
673 auth_data_len, protocol);
677 case SILC_PROTOCOL_STATE_END:
680 * End protocol. Nothing special to be done here.
683 /* Protocol has ended, call the final callback */
684 if (protocol->final_callback)
685 silc_protocol_execute_final(protocol, client->schedule);
687 silc_protocol_free(protocol);
691 case SILC_PROTOCOL_STATE_ERROR:
694 * Error. Send notify to remote.
696 unsigned char error[4];
698 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
700 /* Error in protocol. Send FAILURE packet. Although I don't think
701 this could ever happen on client side. */
702 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
703 NULL, 0, NULL, NULL, error, 4, TRUE);
705 /* On error the final callback is always called. */
706 if (protocol->final_callback)
707 silc_protocol_execute_final(protocol, client->schedule);
709 silc_protocol_free(protocol);
712 case SILC_PROTOCOL_STATE_FAILURE:
714 * Received failure from remote.
717 /* On error the final callback is always called. */
718 if (protocol->final_callback)
719 silc_protocol_execute_final(protocol, client->schedule);
721 silc_protocol_free(protocol);
724 case SILC_PROTOCOL_STATE_UNKNOWN:
730 * Re-key protocol routines
733 /* Actually takes the new keys into use. */
736 silc_client_protocol_rekey_validate(SilcClient client,
737 SilcClientRekeyInternalContext *ctx,
738 SilcSocketConnection sock,
739 SilcSKEKeyMaterial *keymat,
742 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
744 if (ctx->responder == TRUE) {
746 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
747 keymat->enc_key_len);
748 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
749 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
750 keymat->hmac_key_len);
752 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
753 keymat->enc_key_len);
754 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
755 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
756 keymat->hmac_key_len);
760 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
761 keymat->enc_key_len);
762 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
763 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
764 keymat->hmac_key_len);
766 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
767 keymat->enc_key_len);
768 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
769 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
770 keymat->hmac_key_len);
774 /* Save the current sending encryption key */
776 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
777 silc_free(conn->rekey->send_enc_key);
778 conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
779 keymat->enc_key_len / 8);
780 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
784 /* This function actually re-generates (when not using PFS) the keys and
785 takes them into use. */
788 silc_client_protocol_rekey_generate(SilcClient client,
789 SilcClientRekeyInternalContext *ctx,
792 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
793 SilcSKEKeyMaterial *keymat;
794 SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
795 SilcUInt32 hash_len = silc_hash_len(conn->hash);
797 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
798 send ? "sending" : "receiving"));
800 /* Generate the new key */
801 keymat = silc_calloc(1, sizeof(*keymat));
802 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
803 conn->rekey->enc_key_len,
804 16, key_len, hash_len,
807 /* Set the keys into use */
808 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
810 silc_ske_free_key_material(keymat);
813 /* This function actually re-generates (with PFS) the keys and
814 takes them into use. */
817 silc_client_protocol_rekey_generate_pfs(SilcClient client,
818 SilcClientRekeyInternalContext *ctx,
821 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
822 SilcSKEKeyMaterial *keymat;
823 SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
824 SilcUInt32 hash_len = silc_hash_len(conn->hash);
825 unsigned char *tmpbuf;
828 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
829 send ? "sending" : "receiving"));
831 /* Encode KEY to binary data */
832 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
834 /* Generate the new key */
835 keymat = silc_calloc(1, sizeof(*keymat));
836 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
839 /* Set the keys into use */
840 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
842 memset(tmpbuf, 0, klen);
844 silc_ske_free_key_material(keymat);
847 /* Packet sending callback. This function is provided as packet sending
848 routine to the Key Exchange functions. */
851 silc_client_protocol_rekey_send_packet(SilcSKE ske,
856 SilcProtocol protocol = (SilcProtocol)context;
857 SilcClientRekeyInternalContext *ctx =
858 (SilcClientRekeyInternalContext *)protocol->context;
859 SilcClient client = (SilcClient)ctx->client;
861 /* Send the packet immediately */
862 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
863 packet->data, packet->len, FALSE);
866 /* Performs re-key as defined in the SILC protocol specification. */
868 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
870 SilcProtocol protocol = (SilcProtocol)context;
871 SilcClientRekeyInternalContext *ctx =
872 (SilcClientRekeyInternalContext *)protocol->context;
873 SilcClient client = (SilcClient)ctx->client;
874 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
875 SilcSKEStatus status;
877 SILC_LOG_DEBUG(("Start"));
879 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
880 protocol->state = SILC_PROTOCOL_STATE_START;
882 SILC_LOG_DEBUG(("State=%d", protocol->state));
884 switch(protocol->state) {
885 case SILC_PROTOCOL_STATE_START:
891 if (ctx->responder == TRUE) {
893 * We are receiving party
896 if (ctx->pfs == TRUE) {
898 * Use Perfect Forward Secrecy, ie. negotiate the key material
899 * using the SKE protocol.
902 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
903 /* Error in protocol */
904 protocol->state = SILC_PROTOCOL_STATE_ERROR;
905 silc_protocol_execute(protocol, client->schedule, 0, 300000);
908 ctx->ske = silc_ske_alloc(client->rng, client);
909 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
910 silc_ske_group_get_by_number(conn->rekey->ske_group,
911 &ctx->ske->prop->group);
913 silc_ske_set_callbacks(ctx->ske,
914 silc_client_protocol_rekey_send_packet,
915 NULL, NULL, NULL, silc_ske_check_version,
918 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
919 if (status != SILC_SKE_STATUS_OK) {
920 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
923 protocol->state = SILC_PROTOCOL_STATE_ERROR;
924 silc_protocol_execute(protocol, client->schedule, 0, 300000);
928 /* Advance the protocol state */
930 silc_protocol_execute(protocol, client->schedule, 0, 0);
933 * Do normal and simple re-key.
936 /* Send the REKEY_DONE to indicate we will take new keys into use */
937 silc_client_packet_send(client, ctx->sock,
938 SILC_PACKET_REKEY_DONE,
939 NULL, 0, NULL, NULL, NULL, 0, FALSE);
941 /* After we send REKEY_DONE we must set the sending encryption
942 key to the new key since all packets after this packet must
943 encrypted with the new key. */
944 silc_client_protocol_rekey_generate(client, ctx, TRUE);
946 /* The protocol ends in next stage. */
947 protocol->state = SILC_PROTOCOL_STATE_END;
952 * We are the initiator of this protocol
955 /* Start the re-key by sending the REKEY packet */
956 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
957 NULL, 0, NULL, NULL, NULL, 0, FALSE);
959 if (ctx->pfs == TRUE) {
961 * Use Perfect Forward Secrecy, ie. negotiate the key material
962 * using the SKE protocol.
964 ctx->ske = silc_ske_alloc(client->rng, client);
965 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
966 silc_ske_group_get_by_number(conn->rekey->ske_group,
967 &ctx->ske->prop->group);
969 silc_ske_set_callbacks(ctx->ske,
970 silc_client_protocol_rekey_send_packet,
971 NULL, NULL, NULL, silc_ske_check_version,
974 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
975 if (status != SILC_SKE_STATUS_OK) {
976 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
979 protocol->state = SILC_PROTOCOL_STATE_ERROR;
980 silc_protocol_execute(protocol, client->schedule, 0, 300000);
984 /* Advance the protocol state */
988 * Do normal and simple re-key.
991 /* Send the REKEY_DONE to indicate we will take new keys into use
993 silc_client_packet_send(client, ctx->sock,
994 SILC_PACKET_REKEY_DONE,
995 NULL, 0, NULL, NULL, NULL, 0, FALSE);
997 /* After we send REKEY_DONE we must set the sending encryption
998 key to the new key since all packets after this packet must
999 encrypted with the new key. */
1000 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1002 /* The protocol ends in next stage. */
1003 protocol->state = SILC_PROTOCOL_STATE_END;
1011 * Second state, used only when oding re-key with PFS.
1013 if (ctx->responder == TRUE) {
1014 if (ctx->pfs == TRUE) {
1016 * Send our KE packe to the initiator now that we've processed
1017 * the initiator's KE packet.
1019 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1020 SILC_SKE_PK_TYPE_SILC);
1022 if (status != SILC_SKE_STATUS_OK) {
1023 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1026 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1027 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1033 if (ctx->pfs == TRUE) {
1035 * The packet type must be KE packet
1037 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1038 /* Error in protocol */
1039 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1040 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1043 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1044 if (status != SILC_SKE_STATUS_OK) {
1045 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1048 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1049 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1055 /* Send the REKEY_DONE to indicate we will take new keys into use
1057 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1058 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1060 /* After we send REKEY_DONE we must set the sending encryption
1061 key to the new key since all packets after this packet must
1062 encrypted with the new key. */
1063 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1065 /* The protocol ends in next stage. */
1066 protocol->state = SILC_PROTOCOL_STATE_END;
1069 case SILC_PROTOCOL_STATE_END:
1074 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1075 /* Error in protocol */
1076 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1077 silc_protocol_execute(protocol, client->schedule, 0, 0);
1080 /* We received the REKEY_DONE packet and all packets after this is
1081 encrypted with the new key so set the decryption key to the new key */
1082 if (ctx->pfs == TRUE)
1083 silc_client_protocol_rekey_generate_pfs(client, ctx, FALSE);
1085 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1087 /* Protocol has ended, call the final callback */
1088 if (protocol->final_callback)
1089 silc_protocol_execute_final(protocol, client->schedule);
1091 silc_protocol_free(protocol);
1094 case SILC_PROTOCOL_STATE_ERROR:
1099 if (ctx->pfs == TRUE) {
1100 /* Send abort notification */
1101 silc_ske_abort(ctx->ske, ctx->ske->status);
1104 /* On error the final callback is always called. */
1105 if (protocol->final_callback)
1106 silc_protocol_execute_final(protocol, client->schedule);
1108 silc_protocol_free(protocol);
1111 case SILC_PROTOCOL_STATE_FAILURE:
1113 * We have received failure from remote
1116 /* On error the final callback is always called. */
1117 if (protocol->final_callback)
1118 silc_protocol_execute_final(protocol, client->schedule);
1120 silc_protocol_free(protocol);
1123 case SILC_PROTOCOL_STATE_UNKNOWN:
1129 /* Registers protocols used in client */
1131 void silc_client_protocols_register(void)
1133 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1134 silc_client_protocol_connection_auth);
1135 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1136 silc_client_protocol_key_exchange);
1137 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1138 silc_client_protocol_rekey);
1141 /* Unregisters protocols */
1143 void silc_client_protocols_unregister(void)
1145 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1146 silc_client_protocol_connection_auth);
1147 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1148 silc_client_protocol_key_exchange);
1149 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1150 silc_client_protocol_rekey);