5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Client side of the protocols.
25 #include "clientlibincludes.h"
26 #include "client_internal.h"
28 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
29 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
30 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
33 * Key Exhange protocol functions
36 /* Function that is called when SKE protocol sends packets to network. */
38 void silc_client_protocol_ke_send_packet(SilcSKE ske,
43 SilcProtocol protocol = (SilcProtocol)context;
44 SilcClientKEInternalContext *ctx =
45 (SilcClientKEInternalContext *)protocol->context;
46 SilcClient client = (SilcClient)ctx->client;
48 /* Send the packet immediately */
49 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
50 packet->data, packet->len, TRUE);
53 /* Public key verification callback. Called by the application. */
57 SilcSKEVerifyCbCompletion completion;
58 void *completion_context;
61 static void silc_client_verify_key_cb(bool success, void *context)
63 VerifyKeyContext verify = (VerifyKeyContext)context;
65 SILC_LOG_DEBUG(("Start"));
67 /* Call the completion callback back to the SKE */
68 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
69 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
70 verify->completion_context);
75 /* Callback that is called when we have received KE payload from
76 responder. We try to verify the public key now. */
78 void silc_client_protocol_ke_verify_key(SilcSKE ske,
79 unsigned char *pk_data,
81 SilcSKEPKType pk_type,
83 SilcSKEVerifyCbCompletion completion,
84 void *completion_context)
86 SilcProtocol protocol = (SilcProtocol)context;
87 SilcClientKEInternalContext *ctx =
88 (SilcClientKEInternalContext *)protocol->context;
89 SilcClient client = (SilcClient)ctx->client;
90 VerifyKeyContext verify;
92 SILC_LOG_DEBUG(("Start"));
94 verify = silc_calloc(1, sizeof(*verify));
96 verify->completion = completion;
97 verify->completion_context = completion_context;
99 /* Verify public key from user. */
100 client->internal->ops->verify_public_key(client, ctx->sock->user_data,
102 pk_data, pk_len, pk_type,
103 silc_client_verify_key_cb, verify);
106 /* Sets the negotiated key material into use for particular connection. */
108 void silc_client_protocol_ke_set_keys(SilcSKE ske,
109 SilcSocketConnection sock,
110 SilcSKEKeyMaterial *keymat,
115 SilcSKEDiffieHellmanGroup group,
118 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
120 SILC_LOG_DEBUG(("Setting new keys into use"));
122 /* Allocate cipher to be used in the communication */
123 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
124 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
125 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
126 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
128 if (is_responder == TRUE) {
129 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
130 keymat->enc_key_len);
131 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
132 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
133 keymat->enc_key_len);
134 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
135 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
136 keymat->hmac_key_len);
137 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
138 keymat->hmac_key_len);
140 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
141 keymat->enc_key_len);
142 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
143 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
144 keymat->enc_key_len);
145 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
146 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
147 keymat->hmac_key_len);
148 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
149 keymat->hmac_key_len);
153 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
154 conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
155 keymat->enc_key_len / 8);
156 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
158 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
159 conn->rekey->pfs = TRUE;
160 conn->rekey->ske_group = silc_ske_group_get_number(group);
162 /* Save the HASH function */
163 silc_hash_alloc(hash->hash->name, &conn->hash);
166 /* Checks the version string of the server. */
168 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
169 uint32 len, void *context)
171 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
172 SilcClient client = (SilcClient)ske->user_data;
173 SilcSKEStatus status = SILC_SKE_STATUS_OK;
175 int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
177 /* Check for initial version string */
178 if (!strstr(version, "SILC-1.0-"))
179 status = SILC_SKE_STATUS_BAD_VERSION;
181 /* Check software version */
185 status = SILC_SKE_STATUS_BAD_VERSION;
188 cp = strchr(cp, '.');
193 cp = strchr(cp, '.');
195 build = atoi(cp + 1);
197 cp = client->internal->silc_client_version + 9;
199 status = SILC_SKE_STATUS_BAD_VERSION;
202 cp = strchr(cp, '.');
207 cp = strchr(cp, '.');
209 build2 = atoi(cp + 1);
212 status = SILC_SKE_STATUS_BAD_VERSION;
214 /* XXX backward support for 0.6.1 */
215 if (maj == 0 && min == 6 && build < 2)
216 ske->backward_version = 1;
218 if (status != SILC_SKE_STATUS_OK)
219 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
220 "We don't support server version `%s'",
226 /* Callback that is called by the SKE to indicate that it is safe to
227 continue the execution of the protocol. Is given as argument to the
228 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
229 This is called due to the fact that the public key verification
230 process is asynchronous and we must not continue the protocl until
231 the public key has been verified and this callback is called. */
233 static void silc_client_protocol_ke_continue(SilcSKE ske,
236 SilcProtocol protocol = (SilcProtocol)context;
237 SilcClientKEInternalContext *ctx =
238 (SilcClientKEInternalContext *)protocol->context;
239 SilcClient client = (SilcClient)ctx->client;
240 SilcClientConnection conn = ctx->sock->user_data;
242 SILC_LOG_DEBUG(("Start"));
244 if (ske->status != SILC_SKE_STATUS_OK) {
245 /* Call failure client operation */
246 client->internal->ops->failure(client, conn, protocol,
247 (void *)ske->status);
248 protocol->state = SILC_PROTOCOL_STATE_ERROR;
249 silc_protocol_execute(protocol, client->schedule, 0, 0);
253 /* Send Ok to the other end. We will end the protocol as server
254 sends Ok to us when we will take the new keys into use. Do this
255 if we are initiator. This is happens when this callback was sent
256 to silc_ske_initiator_finish function. */
257 if (ctx->responder == FALSE) {
258 silc_ske_end(ctx->ske);
260 /* End the protocol on the next round */
261 protocol->state = SILC_PROTOCOL_STATE_END;
264 /* Advance protocol state and call the next state if we are responder.
265 This happens when this callback was sent to silc_ske_responder_phase_2
267 if (ctx->responder == TRUE) {
269 silc_protocol_execute(protocol, client->schedule, 0, 100000);
273 /* Performs key exchange protocol. This is used for both initiator
274 and responder key exchange. This may be called recursively. */
276 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
278 SilcProtocol protocol = (SilcProtocol)context;
279 SilcClientKEInternalContext *ctx =
280 (SilcClientKEInternalContext *)protocol->context;
281 SilcClient client = (SilcClient)ctx->client;
282 SilcClientConnection conn = ctx->sock->user_data;
283 SilcSKEStatus status = SILC_SKE_STATUS_OK;
285 SILC_LOG_DEBUG(("Start"));
287 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
288 protocol->state = SILC_PROTOCOL_STATE_START;
290 switch(protocol->state) {
291 case SILC_PROTOCOL_STATE_START:
298 /* Allocate Key Exchange object */
299 ctx->ske = ske = silc_ske_alloc(client->rng, 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. */
311 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
312 client->internal->silc_client_version,
313 ctx->packet->buffer, TRUE);
315 SilcSKEStartPayload *start_payload;
317 /* Assemble security properties. */
318 silc_ske_assemble_security_properties(
319 ske, SILC_SKE_SP_FLAG_MUTUAL,
320 client->internal->silc_client_version,
323 /* Start the key exchange by sending our security properties
324 to the remote end. */
325 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
329 /* Return now if the procedure is pending */
330 if (status == SILC_SKE_STATUS_PENDING)
333 if (status != SILC_SKE_STATUS_OK) {
334 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
336 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
339 protocol->state = SILC_PROTOCOL_STATE_ERROR;
340 silc_protocol_execute(protocol, client->schedule, 0, 0);
344 /* Advance protocol state and call the next state if we are responder */
346 if (ctx->responder == TRUE)
347 silc_protocol_execute(protocol, client->schedule, 0, 100000);
355 if (ctx->responder == TRUE) {
356 /* Sends the selected security properties to the initiator. */
357 status = silc_ske_responder_phase_1(ctx->ske);
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,
401 SILC_SKE_PK_TYPE_SILC);
405 /* Return now if the procedure is pending */
406 if (status == SILC_SKE_STATUS_PENDING)
409 if (status != SILC_SKE_STATUS_OK) {
410 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
412 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
415 protocol->state = SILC_PROTOCOL_STATE_ERROR;
416 silc_protocol_execute(protocol, client->schedule, 0, 0);
426 if (ctx->responder == TRUE) {
427 /* This creates the key exchange material and sends our
428 public parts to the initiator inside Key Exchange 2 Payload. */
430 silc_ske_responder_finish(ctx->ske,
431 client->public_key, client->private_key,
432 SILC_SKE_PK_TYPE_SILC);
434 /* End the protocol on the next round */
435 protocol->state = SILC_PROTOCOL_STATE_END;
437 /* Finish the protocol. This verifies the Key Exchange 2 payload
438 sent by responder. The silc_client_protocol_ke_continue will
439 be called after the public key has been verified. */
440 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
443 /* Return now if the procedure is pending */
444 if (status == SILC_SKE_STATUS_PENDING)
447 if (status != SILC_SKE_STATUS_OK) {
448 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
449 client->internal->ops->say(
450 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
451 "Received unsupported server %s public key",
452 ctx->sock->hostname);
454 client->internal->ops->say(
455 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
456 "Error during key exchange protocol with server %s",
457 ctx->sock->hostname);
459 protocol->state = SILC_PROTOCOL_STATE_ERROR;
460 silc_protocol_execute(protocol, client->schedule, 0, 0);
466 case SILC_PROTOCOL_STATE_END:
471 SilcSKEKeyMaterial *keymat;
472 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
473 int hash_len = ctx->ske->prop->hash->hash->hash_len;
475 /* Process the key material */
476 keymat = silc_calloc(1, sizeof(*keymat));
477 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
479 if (status != SILC_SKE_STATUS_OK) {
480 protocol->state = SILC_PROTOCOL_STATE_ERROR;
481 silc_protocol_execute(protocol, client->schedule, 0, 300000);
482 silc_ske_free_key_material(keymat);
485 ctx->keymat = keymat;
487 /* Send Ok to the other end if we are responder. If we are initiator
488 we have sent this already. */
489 if (ctx->responder == TRUE)
490 silc_ske_end(ctx->ske);
492 /* Unregister the timeout task since the protocol has ended.
493 This was the timeout task to be executed if the protocol is
494 not completed fast enough. */
495 if (ctx->timeout_task)
496 silc_schedule_task_del(client->schedule, ctx->timeout_task);
498 /* Protocol has ended, call the final callback */
499 if (protocol->final_callback)
500 silc_protocol_execute_final(protocol, client->schedule);
502 silc_protocol_free(protocol);
506 case SILC_PROTOCOL_STATE_ERROR:
508 * Error during protocol
511 /* Send abort notification */
512 silc_ske_abort(ctx->ske, ctx->ske->status);
514 /* On error the final callback is always called. */
515 if (protocol->final_callback)
516 silc_protocol_execute_final(protocol, client->schedule);
518 silc_protocol_free(protocol);
521 case SILC_PROTOCOL_STATE_FAILURE:
523 * Received failure from remote.
526 /* Unregister the timeout task since the protocol has ended.
527 This was the timeout task to be executed if the protocol is
528 not completed fast enough. */
529 if (ctx->timeout_task)
530 silc_schedule_task_del(client->schedule, ctx->timeout_task);
532 /* On error the final callback is always called. */
533 if (protocol->final_callback)
534 silc_protocol_execute_final(protocol, client->schedule);
536 silc_protocol_free(protocol);
538 case SILC_PROTOCOL_STATE_UNKNOWN:
544 * Connection Authentication protocol functions
548 silc_client_get_public_key_auth(SilcClient client,
549 SilcClientConnection conn,
550 unsigned char *auth_data,
551 uint32 *auth_data_len,
558 /* Use our default key */
561 /* Make the authentication data. Protocol says it is HASH plus
563 len = ske->hash_len + ske->start_payload_copy->len;
564 auth = silc_buffer_alloc(len);
565 silc_buffer_pull_tail(auth, len);
566 silc_buffer_format(auth,
567 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
568 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
569 ske->start_payload_copy->len),
572 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
573 auth->len, auth_data, auth_data_len)) {
574 silc_buffer_free(auth);
578 silc_buffer_free(auth);
582 /* Continues the connection authentication protocol. This funtion may
583 be called directly or used as SilcAskPassphrase callback. */
586 silc_client_conn_auth_continue(unsigned char *auth_data,
587 uint32 auth_data_len, void *context)
589 SilcProtocol protocol = (SilcProtocol)context;
590 SilcClientConnAuthInternalContext *ctx =
591 (SilcClientConnAuthInternalContext *)protocol->context;
592 SilcClient client = (SilcClient)ctx->client;
596 SILC_LOG_DEBUG(("Start"));
598 payload_len = 4 + auth_data_len;
599 packet = silc_buffer_alloc(payload_len);
600 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
601 silc_buffer_format(packet,
602 SILC_STR_UI_SHORT(payload_len),
603 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
604 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
607 /* Send the packet to server */
608 silc_client_packet_send(client, ctx->sock,
609 SILC_PACKET_CONNECTION_AUTH,
611 packet->data, packet->len, TRUE);
612 silc_buffer_free(packet);
614 /* Next state is end of protocol */
615 protocol->state = SILC_PROTOCOL_STATE_END;
618 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
620 SilcProtocol protocol = (SilcProtocol)context;
621 SilcClientConnAuthInternalContext *ctx =
622 (SilcClientConnAuthInternalContext *)protocol->context;
623 SilcClient client = (SilcClient)ctx->client;
624 SilcClientConnection conn = ctx->sock->user_data;
626 SILC_LOG_DEBUG(("Start"));
628 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
629 protocol->state = SILC_PROTOCOL_STATE_START;
631 switch(protocol->state) {
632 case SILC_PROTOCOL_STATE_START:
635 * Start protocol. We send authentication data to the server
636 * to be authenticated.
638 unsigned char *auth_data = NULL;
639 uint32 auth_data_len = 0;
640 unsigned char sign[1024];
642 switch(ctx->auth_meth) {
644 /* No authentication required */
647 case SILC_AUTH_PASSWORD:
648 /* Password authentication */
649 if (ctx->auth_data && ctx->auth_data_len) {
650 auth_data = ctx->auth_data;
651 auth_data_len = ctx->auth_data_len;
655 client->internal->ops->say(
656 client, conn, SILC_CLIENT_MESSAGE_INFO,
657 "Password authentication required by server %s",
658 ctx->sock->hostname);
659 client->internal->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 = silc_memdup(keymat->send_enc_key,
786 keymat->enc_key_len / 8);
787 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
791 /* This function actually re-generates (when not using PFS) the keys and
792 takes them into use. */
795 silc_client_protocol_rekey_generate(SilcClient client,
796 SilcClientRekeyInternalContext *ctx,
799 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
800 SilcSKEKeyMaterial *keymat;
801 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
802 uint32 hash_len = conn->hash->hash->hash_len;
804 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
805 send ? "sending" : "receiving"));
807 /* Generate the new key */
808 keymat = silc_calloc(1, sizeof(*keymat));
809 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
810 conn->rekey->enc_key_len,
811 16, key_len, hash_len,
814 /* Set the keys into use */
815 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
817 silc_ske_free_key_material(keymat);
820 /* This function actually re-generates (with PFS) the keys and
821 takes them into use. */
824 silc_client_protocol_rekey_generate_pfs(SilcClient client,
825 SilcClientRekeyInternalContext *ctx,
828 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
829 SilcSKEKeyMaterial *keymat;
830 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
831 uint32 hash_len = conn->hash->hash->hash_len;
832 unsigned char *tmpbuf;
835 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
836 send ? "sending" : "receiving"));
838 /* Encode KEY to binary data */
839 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
841 /* Generate the new key */
842 keymat = silc_calloc(1, sizeof(*keymat));
843 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
846 /* Set the keys into use */
847 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
849 memset(tmpbuf, 0, klen);
851 silc_ske_free_key_material(keymat);
854 /* Packet sending callback. This function is provided as packet sending
855 routine to the Key Exchange functions. */
858 silc_client_protocol_rekey_send_packet(SilcSKE ske,
863 SilcProtocol protocol = (SilcProtocol)context;
864 SilcClientRekeyInternalContext *ctx =
865 (SilcClientRekeyInternalContext *)protocol->context;
866 SilcClient client = (SilcClient)ctx->client;
868 /* Send the packet immediately */
869 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
870 packet->data, packet->len, FALSE);
873 /* Performs re-key as defined in the SILC protocol specification. */
875 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
877 SilcProtocol protocol = (SilcProtocol)context;
878 SilcClientRekeyInternalContext *ctx =
879 (SilcClientRekeyInternalContext *)protocol->context;
880 SilcClient client = (SilcClient)ctx->client;
881 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
882 SilcSKEStatus status;
884 SILC_LOG_DEBUG(("Start"));
886 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
887 protocol->state = SILC_PROTOCOL_STATE_START;
889 SILC_LOG_DEBUG(("State=%d", protocol->state));
891 switch(protocol->state) {
892 case SILC_PROTOCOL_STATE_START:
898 if (ctx->responder == TRUE) {
900 * We are receiving party
903 if (ctx->pfs == TRUE) {
905 * Use Perfect Forward Secrecy, ie. negotiate the key material
906 * using the SKE protocol.
909 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
910 /* Error in protocol */
911 protocol->state = SILC_PROTOCOL_STATE_ERROR;
912 silc_protocol_execute(protocol, client->schedule, 0, 300000);
915 ctx->ske = silc_ske_alloc(client->rng, client);
916 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
917 silc_ske_group_get_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(client->rng, client);
972 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
973 silc_ske_group_get_by_number(conn->rekey->ske_group,
974 &ctx->ske->prop->group);
976 silc_ske_set_callbacks(ctx->ske,
977 silc_client_protocol_rekey_send_packet,
978 NULL, NULL, NULL, silc_ske_check_version,
981 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
982 if (status != SILC_SKE_STATUS_OK) {
983 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
986 protocol->state = SILC_PROTOCOL_STATE_ERROR;
987 silc_protocol_execute(protocol, client->schedule, 0, 300000);
991 /* Advance the protocol state */
995 * Do normal and simple re-key.
998 /* Send the REKEY_DONE to indicate we will take new keys into use
1000 silc_client_packet_send(client, ctx->sock,
1001 SILC_PACKET_REKEY_DONE,
1002 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1004 /* After we send REKEY_DONE we must set the sending encryption
1005 key to the new key since all packets after this packet must
1006 encrypted with the new key. */
1007 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1009 /* The protocol ends in next stage. */
1010 protocol->state = SILC_PROTOCOL_STATE_END;
1018 * Second state, used only when oding re-key with PFS.
1020 if (ctx->responder == TRUE) {
1021 if (ctx->pfs == TRUE) {
1023 * Send our KE packe to the initiator now that we've processed
1024 * the initiator's KE packet.
1026 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1027 SILC_SKE_PK_TYPE_SILC);
1029 if (status != SILC_SKE_STATUS_OK) {
1030 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1033 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1034 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1040 if (ctx->pfs == TRUE) {
1042 * The packet type must be KE packet
1044 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1045 /* Error in protocol */
1046 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1047 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1050 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1051 if (status != SILC_SKE_STATUS_OK) {
1052 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1055 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1056 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1062 /* Send the REKEY_DONE to indicate we will take new keys into use
1064 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1065 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1067 /* After we send REKEY_DONE we must set the sending encryption
1068 key to the new key since all packets after this packet must
1069 encrypted with the new key. */
1070 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1072 /* The protocol ends in next stage. */
1073 protocol->state = SILC_PROTOCOL_STATE_END;
1076 case SILC_PROTOCOL_STATE_END:
1081 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1082 /* Error in protocol */
1083 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1084 silc_protocol_execute(protocol, client->schedule, 0, 0);
1087 /* We received the REKEY_DONE packet and all packets after this is
1088 encrypted with the new key so set the decryption key to the new key */
1089 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1091 /* Protocol has ended, call the final callback */
1092 if (protocol->final_callback)
1093 silc_protocol_execute_final(protocol, client->schedule);
1095 silc_protocol_free(protocol);
1098 case SILC_PROTOCOL_STATE_ERROR:
1103 if (ctx->pfs == TRUE) {
1104 /* Send abort notification */
1105 silc_ske_abort(ctx->ske, ctx->ske->status);
1108 /* On error the final callback is always called. */
1109 if (protocol->final_callback)
1110 silc_protocol_execute_final(protocol, client->schedule);
1112 silc_protocol_free(protocol);
1115 case SILC_PROTOCOL_STATE_FAILURE:
1117 * We have received failure from remote
1120 /* On error the final callback is always called. */
1121 if (protocol->final_callback)
1122 silc_protocol_execute_final(protocol, client->schedule);
1124 silc_protocol_free(protocol);
1127 case SILC_PROTOCOL_STATE_UNKNOWN:
1133 /* Registers protocols used in client */
1135 void silc_client_protocols_register(void)
1137 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1138 silc_client_protocol_connection_auth);
1139 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1140 silc_client_protocol_key_exchange);
1141 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1142 silc_client_protocol_rekey);
1145 /* Unregisters protocols */
1147 void silc_client_protocols_unregister(void)
1149 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1150 silc_client_protocol_connection_auth);
1151 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1152 silc_client_protocol_key_exchange);
1153 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1154 silc_client_protocol_rekey);