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;
120 const char *cname = silc_cipher_get_name(cipher);
122 SILC_LOG_DEBUG(("Setting new keys into use"));
124 /* Allocate cipher to be used in the communication */
125 silc_cipher_alloc((char *)cname, &conn->send_key);
126 silc_cipher_alloc((char *)cname, &conn->receive_key);
127 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
128 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
130 if (is_responder == TRUE) {
131 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
132 keymat->enc_key_len);
133 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
134 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
135 keymat->enc_key_len);
136 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
137 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
138 keymat->hmac_key_len);
139 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
140 keymat->hmac_key_len);
142 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
143 keymat->enc_key_len);
144 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
145 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
146 keymat->enc_key_len);
147 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
148 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
149 keymat->hmac_key_len);
150 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
151 keymat->hmac_key_len);
155 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
156 conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
157 keymat->enc_key_len / 8);
158 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
160 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
161 conn->rekey->pfs = TRUE;
162 conn->rekey->ske_group = silc_ske_group_get_number(group);
164 /* Save the HASH function */
165 silc_hash_alloc(silc_hash_get_name(hash), &conn->hash);
168 /* Checks the version string of the server. */
170 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
171 SilcUInt32 len, void *context)
173 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
174 SilcClient client = (SilcClient)ske->user_data;
175 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
177 if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
179 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
180 "We don't support server version `%s'",
182 return SILC_SKE_STATUS_BAD_VERSION;
185 if (!silc_parse_version_string(client->internal->silc_client_version,
186 &l_protocol_version, NULL, NULL,
188 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
189 "We don't support server version `%s'",
191 return SILC_SKE_STATUS_BAD_VERSION;
194 /* If remote is too new, don't connect */
195 if (l_protocol_version < r_protocol_version) {
196 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
197 "We don't support server version `%s'",
199 return SILC_SKE_STATUS_BAD_VERSION;
202 ske->sock->version = r_protocol_version;
204 return SILC_SKE_STATUS_OK;
207 /* Callback that is called by the SKE to indicate that it is safe to
208 continue the execution of the protocol. Is given as argument to the
209 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
210 This is called due to the fact that the public key verification
211 process is asynchronous and we must not continue the protocl until
212 the public key has been verified and this callback is called. */
214 static void silc_client_protocol_ke_continue(SilcSKE ske,
217 SilcProtocol protocol = (SilcProtocol)context;
218 SilcClientKEInternalContext *ctx =
219 (SilcClientKEInternalContext *)protocol->context;
220 SilcClient client = (SilcClient)ctx->client;
221 SilcClientConnection conn = ctx->sock->user_data;
223 SILC_LOG_DEBUG(("Start"));
225 if (ske->status != SILC_SKE_STATUS_OK) {
226 /* Call failure client operation */
227 client->internal->ops->failure(client, conn, protocol,
228 (void *)ske->status);
229 protocol->state = SILC_PROTOCOL_STATE_ERROR;
230 silc_protocol_execute(protocol, client->schedule, 0, 0);
234 /* Send Ok to the other end. We will end the protocol as server
235 sends Ok to us when we will take the new keys into use. Do this
236 if we are initiator. This is happens when this callback was sent
237 to silc_ske_initiator_finish function. */
238 if (ctx->responder == FALSE) {
239 silc_ske_end(ctx->ske);
241 /* End the protocol on the next round */
242 protocol->state = SILC_PROTOCOL_STATE_END;
245 /* Advance protocol state and call the next state if we are responder.
246 This happens when this callback was sent to silc_ske_responder_phase_2
248 if (ctx->responder == TRUE) {
250 silc_protocol_execute(protocol, client->schedule, 0, 100000);
254 /* Performs key exchange protocol. This is used for both initiator
255 and responder key exchange. This may be called recursively. */
257 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
259 SilcProtocol protocol = (SilcProtocol)context;
260 SilcClientKEInternalContext *ctx =
261 (SilcClientKEInternalContext *)protocol->context;
262 SilcClient client = (SilcClient)ctx->client;
263 SilcClientConnection conn = ctx->sock->user_data;
264 SilcSKEStatus status = SILC_SKE_STATUS_OK;
266 SILC_LOG_DEBUG(("Start"));
268 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
269 protocol->state = SILC_PROTOCOL_STATE_START;
271 switch(protocol->state) {
272 case SILC_PROTOCOL_STATE_START:
279 /* Allocate Key Exchange object */
280 ctx->ske = ske = silc_ske_alloc(client->rng, client);
282 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
284 silc_client_protocol_ke_continue,
285 silc_ske_check_version,
288 if (ctx->responder == TRUE) {
289 /* Start the key exchange by processing the received security
290 properties packet from initiator. */
292 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
293 client->internal->silc_client_version,
294 ctx->packet->buffer, TRUE);
296 SilcSKEStartPayload *start_payload;
298 /* Assemble security properties. */
299 silc_ske_assemble_security_properties(
300 ske, SILC_SKE_SP_FLAG_MUTUAL,
301 client->internal->silc_client_version,
304 /* Start the key exchange by sending our security properties
305 to the remote end. */
306 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
310 /* Return now if the procedure is pending */
311 if (status == SILC_SKE_STATUS_PENDING)
314 if (status != SILC_SKE_STATUS_OK) {
315 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
317 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
320 protocol->state = SILC_PROTOCOL_STATE_ERROR;
321 silc_protocol_execute(protocol, client->schedule, 0, 0);
325 /* Advance protocol state and call the next state if we are responder */
327 if (ctx->responder == TRUE)
328 silc_protocol_execute(protocol, client->schedule, 0, 100000);
336 if (ctx->responder == TRUE) {
337 /* Sends the selected security properties to the initiator. */
338 status = silc_ske_responder_phase_1(ctx->ske);
340 /* Call Phase-1 function. This processes the Key Exchange Start
341 paylaod reply we just got from the responder. The callback
342 function will receive the processed payload where we will
344 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
347 if (status != SILC_SKE_STATUS_OK) {
348 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
350 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
353 protocol->state = SILC_PROTOCOL_STATE_ERROR;
354 silc_protocol_execute(protocol, client->schedule, 0, 0);
358 /* Advance protocol state and call next state if we are initiator */
360 if (ctx->responder == FALSE)
361 silc_protocol_execute(protocol, client->schedule, 0, 100000);
369 if (ctx->responder == TRUE) {
370 /* Process the received Key Exchange 1 Payload packet from
371 the initiator. This also creates our parts of the Diffie
372 Hellman algorithm. The silc_client_protocol_ke_continue will
373 be called after the public key has been verified. */
374 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
376 /* Call the Phase-2 function. This creates Diffie Hellman
377 key exchange parameters and sends our public part inside
378 Key Exhange 1 Payload to the responder. */
379 status = silc_ske_initiator_phase_2(ctx->ske,
382 SILC_SKE_PK_TYPE_SILC);
386 /* Return now if the procedure is pending */
387 if (status == SILC_SKE_STATUS_PENDING)
390 if (status != SILC_SKE_STATUS_OK) {
391 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
393 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
396 protocol->state = SILC_PROTOCOL_STATE_ERROR;
397 silc_protocol_execute(protocol, client->schedule, 0, 0);
407 if (ctx->responder == TRUE) {
408 /* This creates the key exchange material and sends our
409 public parts to the initiator inside Key Exchange 2 Payload. */
411 silc_ske_responder_finish(ctx->ske,
412 client->public_key, client->private_key,
413 SILC_SKE_PK_TYPE_SILC);
415 /* End the protocol on the next round */
416 protocol->state = SILC_PROTOCOL_STATE_END;
418 /* Finish the protocol. This verifies the Key Exchange 2 payload
419 sent by responder. The silc_client_protocol_ke_continue will
420 be called after the public key has been verified. */
421 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
424 /* Return now if the procedure is pending */
425 if (status == SILC_SKE_STATUS_PENDING)
428 if (status != SILC_SKE_STATUS_OK) {
429 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
430 client->internal->ops->say(
431 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
432 "Received unsupported server %s public key",
433 ctx->sock->hostname);
435 client->internal->ops->say(
436 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
437 "Error during key exchange protocol with server %s",
438 ctx->sock->hostname);
440 protocol->state = SILC_PROTOCOL_STATE_ERROR;
441 silc_protocol_execute(protocol, client->schedule, 0, 0);
447 case SILC_PROTOCOL_STATE_END:
452 SilcSKEKeyMaterial *keymat;
453 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
454 int hash_len = silc_hash_len(ctx->ske->prop->hash);
456 /* Process the key material */
457 keymat = silc_calloc(1, sizeof(*keymat));
458 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
460 if (status != SILC_SKE_STATUS_OK) {
461 protocol->state = SILC_PROTOCOL_STATE_ERROR;
462 silc_protocol_execute(protocol, client->schedule, 0, 300000);
463 silc_ske_free_key_material(keymat);
466 ctx->keymat = keymat;
468 /* Send Ok to the other end if we are responder. If we are initiator
469 we have sent this already. */
470 if (ctx->responder == TRUE)
471 silc_ske_end(ctx->ske);
473 /* Unregister the timeout task since the protocol has ended.
474 This was the timeout task to be executed if the protocol is
475 not completed fast enough. */
476 if (ctx->timeout_task)
477 silc_schedule_task_del(client->schedule, ctx->timeout_task);
479 /* Protocol has ended, call the final callback */
480 if (protocol->final_callback)
481 silc_protocol_execute_final(protocol, client->schedule);
483 silc_protocol_free(protocol);
487 case SILC_PROTOCOL_STATE_ERROR:
489 * Error during protocol
492 /* Send abort notification */
493 silc_ske_abort(ctx->ske, ctx->ske->status);
495 /* On error the final callback is always called. */
496 if (protocol->final_callback)
497 silc_protocol_execute_final(protocol, client->schedule);
499 silc_protocol_free(protocol);
502 case SILC_PROTOCOL_STATE_FAILURE:
504 * Received failure from remote.
507 /* Unregister the timeout task since the protocol has ended.
508 This was the timeout task to be executed if the protocol is
509 not completed fast enough. */
510 if (ctx->timeout_task)
511 silc_schedule_task_del(client->schedule, ctx->timeout_task);
513 /* On error the final callback is always called. */
514 if (protocol->final_callback)
515 silc_protocol_execute_final(protocol, client->schedule);
517 silc_protocol_free(protocol);
519 case SILC_PROTOCOL_STATE_UNKNOWN:
525 * Connection Authentication protocol functions
529 silc_client_get_public_key_auth(SilcClient client,
530 SilcClientConnection conn,
531 unsigned char *auth_data,
532 SilcUInt32 *auth_data_len,
539 /* Use our default key */
542 /* Make the authentication data. Protocol says it is HASH plus
544 len = ske->hash_len + ske->start_payload_copy->len;
545 auth = silc_buffer_alloc(len);
546 silc_buffer_pull_tail(auth, len);
547 silc_buffer_format(auth,
548 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
549 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
550 ske->start_payload_copy->len),
553 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
554 auth->len, auth_data, auth_data_len)) {
555 silc_buffer_free(auth);
559 silc_buffer_free(auth);
563 /* Continues the connection authentication protocol. This funtion may
564 be called directly or used as SilcAskPassphrase callback. */
567 silc_client_conn_auth_continue(unsigned char *auth_data,
568 SilcUInt32 auth_data_len, void *context)
570 SilcProtocol protocol = (SilcProtocol)context;
571 SilcClientConnAuthInternalContext *ctx =
572 (SilcClientConnAuthInternalContext *)protocol->context;
573 SilcClient client = (SilcClient)ctx->client;
576 unsigned char *autf8 = NULL;
578 SILC_LOG_DEBUG(("Sending authentication to server"));
580 /* Passphrase must be UTF-8 encoded, if it isn't encode it */
581 if (ctx->auth_meth == SILC_AUTH_PASSWORD &&
582 !silc_utf8_valid(auth_data, auth_data_len)) {
583 payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
585 autf8 = silc_calloc(payload_len, sizeof(*autf8));
586 auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
587 SILC_STRING_ASCII, autf8, payload_len);
591 payload_len = 4 + auth_data_len;
592 packet = silc_buffer_alloc(payload_len);
593 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
594 silc_buffer_format(packet,
595 SILC_STR_UI_SHORT(payload_len),
596 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
597 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
600 /* Send the packet to server */
601 silc_client_packet_send(client, ctx->sock,
602 SILC_PACKET_CONNECTION_AUTH,
604 packet->data, packet->len, TRUE);
605 silc_buffer_free(packet);
608 /* Next state is end of protocol */
609 protocol->state = SILC_PROTOCOL_STATE_END;
612 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
614 SilcProtocol protocol = (SilcProtocol)context;
615 SilcClientConnAuthInternalContext *ctx =
616 (SilcClientConnAuthInternalContext *)protocol->context;
617 SilcClient client = (SilcClient)ctx->client;
618 SilcClientConnection conn = ctx->sock->user_data;
620 SILC_LOG_DEBUG(("Start"));
622 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
623 protocol->state = SILC_PROTOCOL_STATE_START;
625 switch(protocol->state) {
626 case SILC_PROTOCOL_STATE_START:
629 * Start protocol. We send authentication data to the server
630 * to be authenticated.
632 unsigned char *auth_data = NULL;
633 SilcUInt32 auth_data_len = 0;
634 unsigned char sign[1024];
636 switch(ctx->auth_meth) {
638 /* No authentication required */
641 case SILC_AUTH_PASSWORD:
642 /* Password authentication */
643 if (ctx->auth_data && ctx->auth_data_len) {
644 auth_data = ctx->auth_data;
645 auth_data_len = ctx->auth_data_len;
649 client->internal->ops->say(
650 client, conn, SILC_CLIENT_MESSAGE_INFO,
651 "Password authentication required by server %s",
652 ctx->sock->hostname);
653 client->internal->ops->ask_passphrase(client, conn,
654 silc_client_conn_auth_continue,
659 case SILC_AUTH_PUBLIC_KEY:
660 if (!ctx->auth_data) {
661 /* Public key authentication */
662 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
666 auth_data = ctx->auth_data;
667 auth_data_len = ctx->auth_data_len;
673 silc_client_conn_auth_continue(auth_data,
674 auth_data_len, protocol);
678 case SILC_PROTOCOL_STATE_END:
681 * End protocol. Nothing special to be done here.
684 /* Protocol has ended, call the final callback */
685 if (protocol->final_callback)
686 silc_protocol_execute_final(protocol, client->schedule);
688 silc_protocol_free(protocol);
692 case SILC_PROTOCOL_STATE_ERROR:
695 * Error. Send notify to remote.
697 unsigned char error[4];
699 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
701 /* Error in protocol. Send FAILURE packet. Although I don't think
702 this could ever happen on client side. */
703 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
704 NULL, 0, NULL, NULL, error, 4, TRUE);
706 /* On error the final callback is always called. */
707 if (protocol->final_callback)
708 silc_protocol_execute_final(protocol, client->schedule);
710 silc_protocol_free(protocol);
713 case SILC_PROTOCOL_STATE_FAILURE:
715 * Received failure from remote.
718 /* On error the final callback is always called. */
719 if (protocol->final_callback)
720 silc_protocol_execute_final(protocol, client->schedule);
722 silc_protocol_free(protocol);
725 case SILC_PROTOCOL_STATE_UNKNOWN:
731 * Re-key protocol routines
734 /* Actually takes the new keys into use. */
737 silc_client_protocol_rekey_validate(SilcClient client,
738 SilcClientRekeyInternalContext *ctx,
739 SilcSocketConnection sock,
740 SilcSKEKeyMaterial *keymat,
743 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
745 if (ctx->responder == TRUE) {
747 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
748 keymat->enc_key_len);
749 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
750 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
751 keymat->hmac_key_len);
753 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
754 keymat->enc_key_len);
755 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
756 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
757 keymat->hmac_key_len);
761 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
762 keymat->enc_key_len);
763 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
764 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
765 keymat->hmac_key_len);
767 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
768 keymat->enc_key_len);
769 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
770 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
771 keymat->hmac_key_len);
775 /* Save the current sending encryption key */
777 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
778 silc_free(conn->rekey->send_enc_key);
779 conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
780 keymat->enc_key_len / 8);
781 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
785 /* This function actually re-generates (when not using PFS) the keys and
786 takes them into use. */
789 silc_client_protocol_rekey_generate(SilcClient client,
790 SilcClientRekeyInternalContext *ctx,
793 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
794 SilcSKEKeyMaterial *keymat;
795 SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
796 SilcUInt32 hash_len = silc_hash_len(conn->hash);
798 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
799 send ? "sending" : "receiving"));
801 /* Generate the new key */
802 keymat = silc_calloc(1, sizeof(*keymat));
803 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
804 conn->rekey->enc_key_len,
805 16, key_len, hash_len,
808 /* Set the keys into use */
809 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
811 silc_ske_free_key_material(keymat);
814 /* This function actually re-generates (with PFS) the keys and
815 takes them into use. */
818 silc_client_protocol_rekey_generate_pfs(SilcClient client,
819 SilcClientRekeyInternalContext *ctx,
822 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
823 SilcSKEKeyMaterial *keymat;
824 SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
825 SilcUInt32 hash_len = silc_hash_len(conn->hash);
826 unsigned char *tmpbuf;
829 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
830 send ? "sending" : "receiving"));
832 /* Encode KEY to binary data */
833 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
835 /* Generate the new key */
836 keymat = silc_calloc(1, sizeof(*keymat));
837 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
840 /* Set the keys into use */
841 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
843 memset(tmpbuf, 0, klen);
845 silc_ske_free_key_material(keymat);
848 /* Packet sending callback. This function is provided as packet sending
849 routine to the Key Exchange functions. */
852 silc_client_protocol_rekey_send_packet(SilcSKE ske,
857 SilcProtocol protocol = (SilcProtocol)context;
858 SilcClientRekeyInternalContext *ctx =
859 (SilcClientRekeyInternalContext *)protocol->context;
860 SilcClient client = (SilcClient)ctx->client;
862 /* Send the packet immediately */
863 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
864 packet->data, packet->len, FALSE);
867 /* Performs re-key as defined in the SILC protocol specification. */
869 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
871 SilcProtocol protocol = (SilcProtocol)context;
872 SilcClientRekeyInternalContext *ctx =
873 (SilcClientRekeyInternalContext *)protocol->context;
874 SilcClient client = (SilcClient)ctx->client;
875 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
876 SilcSKEStatus status;
878 SILC_LOG_DEBUG(("Start"));
880 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
881 protocol->state = SILC_PROTOCOL_STATE_START;
883 SILC_LOG_DEBUG(("State=%d", protocol->state));
885 switch(protocol->state) {
886 case SILC_PROTOCOL_STATE_START:
892 if (ctx->responder == TRUE) {
894 * We are receiving party
897 if (ctx->pfs == TRUE) {
899 * Use Perfect Forward Secrecy, ie. negotiate the key material
900 * using the SKE protocol.
903 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
904 /* Error in protocol */
905 protocol->state = SILC_PROTOCOL_STATE_ERROR;
906 silc_protocol_execute(protocol, client->schedule, 0, 300000);
909 ctx->ske = silc_ske_alloc(client->rng, client);
910 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
911 silc_ske_group_get_by_number(conn->rekey->ske_group,
912 &ctx->ske->prop->group);
914 silc_ske_set_callbacks(ctx->ske,
915 silc_client_protocol_rekey_send_packet,
916 NULL, NULL, NULL, silc_ske_check_version,
919 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
920 if (status != SILC_SKE_STATUS_OK) {
921 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
924 protocol->state = SILC_PROTOCOL_STATE_ERROR;
925 silc_protocol_execute(protocol, client->schedule, 0, 300000);
929 /* Advance the protocol state */
931 silc_protocol_execute(protocol, client->schedule, 0, 0);
934 * Do normal and simple re-key.
937 /* Send the REKEY_DONE to indicate we will take new keys into use */
938 silc_client_packet_send(client, ctx->sock,
939 SILC_PACKET_REKEY_DONE,
940 NULL, 0, NULL, NULL, NULL, 0, FALSE);
942 /* After we send REKEY_DONE we must set the sending encryption
943 key to the new key since all packets after this packet must
944 encrypted with the new key. */
945 silc_client_protocol_rekey_generate(client, ctx, TRUE);
947 /* The protocol ends in next stage. */
948 protocol->state = SILC_PROTOCOL_STATE_END;
953 * We are the initiator of this protocol
956 /* Start the re-key by sending the REKEY packet */
957 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
958 NULL, 0, NULL, NULL, NULL, 0, FALSE);
960 if (ctx->pfs == TRUE) {
962 * Use Perfect Forward Secrecy, ie. negotiate the key material
963 * using the SKE protocol.
965 ctx->ske = silc_ske_alloc(client->rng, client);
966 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
967 silc_ske_group_get_by_number(conn->rekey->ske_group,
968 &ctx->ske->prop->group);
970 silc_ske_set_callbacks(ctx->ske,
971 silc_client_protocol_rekey_send_packet,
972 NULL, NULL, NULL, silc_ske_check_version,
975 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
976 if (status != SILC_SKE_STATUS_OK) {
977 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
980 protocol->state = SILC_PROTOCOL_STATE_ERROR;
981 silc_protocol_execute(protocol, client->schedule, 0, 300000);
985 /* Advance the protocol state */
989 * Do normal and simple re-key.
992 /* Send the REKEY_DONE to indicate we will take new keys into use
994 silc_client_packet_send(client, ctx->sock,
995 SILC_PACKET_REKEY_DONE,
996 NULL, 0, NULL, NULL, NULL, 0, FALSE);
998 /* After we send REKEY_DONE we must set the sending encryption
999 key to the new key since all packets after this packet must
1000 encrypted with the new key. */
1001 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1003 /* The protocol ends in next stage. */
1004 protocol->state = SILC_PROTOCOL_STATE_END;
1012 * Second state, used only when oding re-key with PFS.
1014 if (ctx->responder == TRUE) {
1015 if (ctx->pfs == TRUE) {
1017 * Send our KE packe to the initiator now that we've processed
1018 * the initiator's KE packet.
1020 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1021 SILC_SKE_PK_TYPE_SILC);
1023 if (status != SILC_SKE_STATUS_OK) {
1024 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1027 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1028 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1034 if (ctx->pfs == TRUE) {
1036 * The packet type must be KE packet
1038 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1039 /* Error in protocol */
1040 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1041 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1044 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1045 if (status != SILC_SKE_STATUS_OK) {
1046 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1049 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1050 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1056 /* Send the REKEY_DONE to indicate we will take new keys into use
1058 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1059 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1061 /* After we send REKEY_DONE we must set the sending encryption
1062 key to the new key since all packets after this packet must
1063 encrypted with the new key. */
1064 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1066 /* The protocol ends in next stage. */
1067 protocol->state = SILC_PROTOCOL_STATE_END;
1070 case SILC_PROTOCOL_STATE_END:
1075 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1076 /* Error in protocol */
1077 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1078 silc_protocol_execute(protocol, client->schedule, 0, 0);
1081 /* We received the REKEY_DONE packet and all packets after this is
1082 encrypted with the new key so set the decryption key to the new key */
1083 if (ctx->pfs == TRUE)
1084 silc_client_protocol_rekey_generate_pfs(client, ctx, FALSE);
1086 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1088 /* Protocol has ended, call the final callback */
1089 if (protocol->final_callback)
1090 silc_protocol_execute_final(protocol, client->schedule);
1092 silc_protocol_free(protocol);
1095 case SILC_PROTOCOL_STATE_ERROR:
1100 if (ctx->pfs == TRUE) {
1101 /* Send abort notification */
1102 silc_ske_abort(ctx->ske, ctx->ske->status);
1105 /* On error the final callback is always called. */
1106 if (protocol->final_callback)
1107 silc_protocol_execute_final(protocol, client->schedule);
1109 silc_protocol_free(protocol);
1112 case SILC_PROTOCOL_STATE_FAILURE:
1114 * We have received failure from remote
1117 /* On error the final callback is always called. */
1118 if (protocol->final_callback)
1119 silc_protocol_execute_final(protocol, client->schedule);
1121 silc_protocol_free(protocol);
1124 case SILC_PROTOCOL_STATE_UNKNOWN:
1130 /* Registers protocols used in client */
1132 void silc_client_protocols_register(void)
1134 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1135 silc_client_protocol_connection_auth);
1136 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1137 silc_client_protocol_key_exchange);
1138 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1139 silc_client_protocol_rekey);
1142 /* Unregisters protocols */
1144 void silc_client_protocols_unregister(void)
1146 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1147 silc_client_protocol_connection_auth);
1148 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1149 silc_client_protocol_key_exchange);
1150 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1151 silc_client_protocol_rekey);