5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2004 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "silcincludes.h"
22 #include "silcclient.h"
23 #include "client_internal.h"
25 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
26 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
27 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
30 * Key Exhange protocol functions
33 /* Function that is called when SKE protocol sends packets to network. */
35 void silc_client_protocol_ke_send_packet(SilcSKE ske,
40 SilcProtocol protocol = (SilcProtocol)context;
41 SilcClientKEInternalContext *ctx =
42 (SilcClientKEInternalContext *)protocol->context;
43 SilcClient client = (SilcClient)ctx->client;
45 /* Send the packet immediately */
46 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
47 packet->data, packet->len, TRUE);
50 /* Public key verification callback. Called by the application. */
54 SilcSKEVerifyCbCompletion completion;
55 void *completion_context;
58 static void silc_client_verify_key_cb(bool success, void *context)
60 VerifyKeyContext verify = (VerifyKeyContext)context;
62 SILC_LOG_DEBUG(("Start"));
64 /* Call the completion callback back to the SKE */
65 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
66 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
67 verify->completion_context);
72 /* Callback that is called when we have received KE payload from
73 responder. We try to verify the public key now. */
75 void silc_client_protocol_ke_verify_key(SilcSKE ske,
76 unsigned char *pk_data,
78 SilcSKEPKType pk_type,
80 SilcSKEVerifyCbCompletion completion,
81 void *completion_context)
83 SilcProtocol protocol = (SilcProtocol)context;
84 SilcClientKEInternalContext *ctx =
85 (SilcClientKEInternalContext *)protocol->context;
86 SilcClient client = (SilcClient)ctx->client;
87 VerifyKeyContext verify;
89 SILC_LOG_DEBUG(("Start"));
91 verify = silc_calloc(1, sizeof(*verify));
93 verify->completion = completion;
94 verify->completion_context = completion_context;
96 /* Verify public key from user. */
97 client->internal->ops->verify_public_key(client, ctx->sock->user_data,
99 pk_data, pk_len, pk_type,
100 silc_client_verify_key_cb, verify);
103 /* Sets the negotiated key material into use for particular connection. */
105 void silc_client_protocol_ke_set_keys(SilcSKE ske,
106 SilcSocketConnection sock,
107 SilcSKEKeyMaterial *keymat,
112 SilcSKEDiffieHellmanGroup group,
115 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
116 const char *cname = silc_cipher_get_name(cipher);
118 SILC_LOG_DEBUG(("Setting new keys into use"));
120 /* Allocate cipher to be used in the communication */
121 silc_cipher_alloc((char *)cname, &conn->internal->send_key);
122 silc_cipher_alloc((char *)cname, &conn->internal->receive_key);
123 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
124 &conn->internal->hmac_send);
125 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
126 &conn->internal->hmac_receive);
128 if (is_responder == TRUE) {
129 silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
130 keymat->enc_key_len);
131 silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv);
132 silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
133 keymat->enc_key_len);
134 silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv);
135 silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
136 keymat->hmac_key_len);
137 silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
138 keymat->hmac_key_len);
140 silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
141 keymat->enc_key_len);
142 silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv);
143 silc_cipher_set_key(conn->internal->receive_key, keymat->receive_enc_key,
144 keymat->enc_key_len);
145 silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv);
146 silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
147 keymat->hmac_key_len);
148 silc_hmac_set_key(conn->internal->hmac_receive, keymat->receive_hmac_key,
149 keymat->hmac_key_len);
153 conn->internal->rekey = silc_calloc(1, sizeof(*conn->internal->rekey));
154 conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
155 keymat->enc_key_len / 8);
156 conn->internal->rekey->enc_key_len = keymat->enc_key_len / 8;
158 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
159 conn->internal->rekey->pfs = TRUE;
160 conn->internal->rekey->ske_group = silc_ske_group_get_number(group);
162 /* Save the HASH function */
163 silc_hash_alloc(silc_hash_get_name(hash), &conn->internal->hash);
166 /* Checks the version string of the server. */
168 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
169 SilcUInt32 len, void *context)
171 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
172 SilcClient client = (SilcClient)ske->user_data;
173 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
175 if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
177 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
178 "We don't support server version `%s'",
180 return SILC_SKE_STATUS_BAD_VERSION;
183 if (!silc_parse_version_string(client->internal->silc_client_version,
184 &l_protocol_version, NULL, NULL,
186 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
187 "We don't support server version `%s'",
189 return SILC_SKE_STATUS_BAD_VERSION;
192 /* If remote is too new, don't connect */
193 if (l_protocol_version < r_protocol_version) {
194 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
195 "We don't support server version `%s'",
197 return SILC_SKE_STATUS_BAD_VERSION;
200 ske->sock->version = r_protocol_version;
202 return SILC_SKE_STATUS_OK;
205 /* Callback that is called by the SKE to indicate that it is safe to
206 continue the execution of the protocol. Is given as argument to the
207 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
208 This is called due to the fact that the public key verification
209 process is asynchronous and we must not continue the protocl until
210 the public key has been verified and this callback is called. */
212 static void silc_client_protocol_ke_continue(SilcSKE ske,
215 SilcProtocol protocol = (SilcProtocol)context;
216 SilcClientKEInternalContext *ctx =
217 (SilcClientKEInternalContext *)protocol->context;
218 SilcClient client = (SilcClient)ctx->client;
219 SilcClientConnection conn = ctx->sock->user_data;
221 SILC_LOG_DEBUG(("Start"));
223 if (ske->status != SILC_SKE_STATUS_OK) {
224 /* Call failure client operation */
225 client->internal->ops->failure(client, conn, protocol,
226 (void *)ske->status);
227 protocol->state = SILC_PROTOCOL_STATE_ERROR;
228 silc_protocol_execute(protocol, client->schedule, 0, 0);
232 /* Send Ok to the other end. We will end the protocol as server
233 sends Ok to us when we will take the new keys into use. Do this
234 if we are initiator. This is happens when this callback was sent
235 to silc_ske_initiator_finish function. */
236 if (ctx->responder == FALSE) {
237 silc_ske_end(ctx->ske);
239 /* End the protocol on the next round */
240 protocol->state = SILC_PROTOCOL_STATE_END;
243 /* Advance protocol state and call the next state if we are responder.
244 This happens when this callback was sent to silc_ske_responder_phase_2
246 if (ctx->responder == TRUE) {
248 silc_protocol_execute(protocol, client->schedule, 0, 1);
252 /* Performs key exchange protocol. This is used for both initiator
253 and responder key exchange. This may be called recursively. */
255 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
257 SilcProtocol protocol = (SilcProtocol)context;
258 SilcClientKEInternalContext *ctx =
259 (SilcClientKEInternalContext *)protocol->context;
260 SilcClient client = (SilcClient)ctx->client;
261 SilcClientConnection conn = ctx->sock->user_data;
262 SilcSKEStatus status = SILC_SKE_STATUS_OK;
264 SILC_LOG_DEBUG(("Start"));
266 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
267 protocol->state = SILC_PROTOCOL_STATE_START;
269 switch(protocol->state) {
270 case SILC_PROTOCOL_STATE_START:
277 /* Allocate Key Exchange object */
278 ctx->ske = ske = silc_ske_alloc(client->rng, client);
280 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
282 silc_client_protocol_ke_continue,
283 silc_ske_check_version,
286 if (ctx->responder == TRUE) {
287 /* Start the key exchange by processing the received security
288 properties packet from initiator. */
290 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
291 client->internal->silc_client_version,
292 ctx->packet->buffer, TRUE);
294 SilcSKEStartPayload *start_payload;
296 /* Assemble security properties. */
297 silc_ske_assemble_security_properties(
298 ske, SILC_SKE_SP_FLAG_MUTUAL,
299 client->internal->silc_client_version,
302 /* Start the key exchange by sending our security properties
303 to the remote end. */
304 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
308 /* Return now if the procedure is pending */
309 if (status == SILC_SKE_STATUS_PENDING)
312 if (status != SILC_SKE_STATUS_OK) {
313 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
315 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
318 protocol->state = SILC_PROTOCOL_STATE_ERROR;
319 silc_protocol_execute(protocol, client->schedule, 0, 0);
323 /* Advance protocol state and call the next state if we are responder */
325 if (ctx->responder == TRUE)
326 silc_protocol_execute(protocol, client->schedule, 0, 1);
334 if (ctx->responder == TRUE) {
335 /* Sends the selected security properties to the initiator. */
336 status = silc_ske_responder_phase_1(ctx->ske);
338 /* Call Phase-1 function. This processes the Key Exchange Start
339 paylaod reply we just got from the responder. The callback
340 function will receive the processed payload where we will
342 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
345 if (status != SILC_SKE_STATUS_OK) {
346 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
348 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
351 protocol->state = SILC_PROTOCOL_STATE_ERROR;
352 silc_protocol_execute(protocol, client->schedule, 0, 0);
356 /* Advance protocol state and call next state if we are initiator */
358 if (ctx->responder == FALSE)
359 silc_protocol_execute(protocol, client->schedule, 0, 1);
367 if (ctx->responder == TRUE) {
368 /* Process the received Key Exchange 1 Payload packet from
369 the initiator. This also creates our parts of the Diffie
370 Hellman algorithm. The silc_client_protocol_ke_continue will
371 be called after the public key has been verified. */
372 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
374 /* Call the Phase-2 function. This creates Diffie Hellman
375 key exchange parameters and sends our public part inside
376 Key Exhange 1 Payload to the responder. */
377 status = silc_ske_initiator_phase_2(ctx->ske,
380 SILC_SKE_PK_TYPE_SILC);
384 /* Return now if the procedure is pending */
385 if (status == SILC_SKE_STATUS_PENDING)
388 if (status != SILC_SKE_STATUS_OK) {
389 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
391 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
394 protocol->state = SILC_PROTOCOL_STATE_ERROR;
395 silc_protocol_execute(protocol, client->schedule, 0, 0);
405 if (ctx->responder == TRUE) {
406 /* This creates the key exchange material and sends our
407 public parts to the initiator inside Key Exchange 2 Payload. */
409 silc_ske_responder_finish(ctx->ske,
410 client->public_key, client->private_key,
411 SILC_SKE_PK_TYPE_SILC);
413 /* End the protocol on the next round */
414 protocol->state = SILC_PROTOCOL_STATE_END;
416 /* Finish the protocol. This verifies the Key Exchange 2 payload
417 sent by responder. The silc_client_protocol_ke_continue will
418 be called after the public key has been verified. */
419 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
422 /* Return now if the procedure is pending */
423 if (status == SILC_SKE_STATUS_PENDING)
426 if (status != SILC_SKE_STATUS_OK) {
427 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
428 client->internal->ops->say(
429 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
430 "Received unsupported server %s public key",
431 ctx->sock->hostname);
433 client->internal->ops->say(
434 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
435 "Error during key exchange protocol with server %s",
436 ctx->sock->hostname);
438 protocol->state = SILC_PROTOCOL_STATE_ERROR;
439 silc_protocol_execute(protocol, client->schedule, 0, 0);
445 case SILC_PROTOCOL_STATE_END:
450 SilcSKEKeyMaterial *keymat;
451 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
452 int hash_len = silc_hash_len(ctx->ske->prop->hash);
454 /* Process the key material */
455 keymat = silc_calloc(1, sizeof(*keymat));
456 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
458 if (status != SILC_SKE_STATUS_OK) {
459 protocol->state = SILC_PROTOCOL_STATE_ERROR;
460 silc_protocol_execute(protocol, client->schedule, 0, 300000);
461 silc_ske_free_key_material(keymat);
464 ctx->keymat = keymat;
466 /* Send Ok to the other end if we are responder. If we are initiator
467 we have sent this already. */
468 if (ctx->responder == TRUE)
469 silc_ske_end(ctx->ske);
471 /* Unregister the timeout task since the protocol has ended.
472 This was the timeout task to be executed if the protocol is
473 not completed fast enough. */
474 if (ctx->timeout_task)
475 silc_schedule_task_del(client->schedule, ctx->timeout_task);
477 /* Protocol has ended, call the final callback */
478 if (protocol->final_callback)
479 silc_protocol_execute_final(protocol, client->schedule);
481 silc_protocol_free(protocol);
485 case SILC_PROTOCOL_STATE_ERROR:
487 * Error during protocol
490 /* Send abort notification */
491 silc_ske_abort(ctx->ske, ctx->ske->status);
493 /* On error the final callback is always called. */
494 if (protocol->final_callback)
495 silc_protocol_execute_final(protocol, client->schedule);
497 silc_protocol_free(protocol);
500 case SILC_PROTOCOL_STATE_FAILURE:
502 * Received failure from remote.
505 /* Unregister the timeout task since the protocol has ended.
506 This was the timeout task to be executed if the protocol is
507 not completed fast enough. */
508 if (ctx->timeout_task)
509 silc_schedule_task_del(client->schedule, ctx->timeout_task);
511 /* On error the final callback is always called. */
512 if (protocol->final_callback)
513 silc_protocol_execute_final(protocol, client->schedule);
515 silc_protocol_free(protocol);
517 case SILC_PROTOCOL_STATE_UNKNOWN:
523 * Connection Authentication protocol functions
527 silc_client_get_public_key_auth(SilcClient client,
528 SilcClientConnection conn,
529 unsigned char *auth_data,
530 SilcUInt32 *auth_data_len,
537 /* Use our default key */
540 /* Make the authentication data. Protocol says it is HASH plus
542 len = ske->hash_len + ske->start_payload_copy->len;
543 auth = silc_buffer_alloc(len);
544 silc_buffer_pull_tail(auth, len);
545 silc_buffer_format(auth,
546 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
547 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
548 ske->start_payload_copy->len),
551 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
552 auth->len, auth_data, auth_data_len)) {
553 silc_buffer_free(auth);
557 silc_buffer_free(auth);
561 /* Continues the connection authentication protocol. This funtion may
562 be called directly or used as SilcAskPassphrase callback. */
565 silc_client_conn_auth_continue(unsigned char *auth_data,
566 SilcUInt32 auth_data_len, void *context)
568 SilcProtocol protocol = (SilcProtocol)context;
569 SilcClientConnAuthInternalContext *ctx =
570 (SilcClientConnAuthInternalContext *)protocol->context;
571 SilcClient client = (SilcClient)ctx->client;
574 unsigned char *autf8 = NULL;
576 SILC_LOG_DEBUG(("Sending authentication to server"));
578 /* Passphrase must be UTF-8 encoded, if it isn't encode it */
579 if (ctx->auth_meth == SILC_AUTH_PASSWORD &&
580 !silc_utf8_valid(auth_data, auth_data_len)) {
581 payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
583 autf8 = silc_calloc(payload_len, sizeof(*autf8));
584 auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
585 SILC_STRING_ASCII, autf8, payload_len);
589 payload_len = 4 + auth_data_len;
590 packet = silc_buffer_alloc(payload_len);
591 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
592 silc_buffer_format(packet,
593 SILC_STR_UI_SHORT(payload_len),
594 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
595 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
598 /* Send the packet to server */
599 silc_client_packet_send(client, ctx->sock,
600 SILC_PACKET_CONNECTION_AUTH,
602 packet->data, packet->len, TRUE);
603 silc_buffer_free(packet);
606 /* Next state is end of protocol */
607 protocol->state = SILC_PROTOCOL_STATE_END;
610 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
612 SilcProtocol protocol = (SilcProtocol)context;
613 SilcClientConnAuthInternalContext *ctx =
614 (SilcClientConnAuthInternalContext *)protocol->context;
615 SilcClient client = (SilcClient)ctx->client;
616 SilcClientConnection conn = ctx->sock->user_data;
618 SILC_LOG_DEBUG(("Start"));
620 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
621 protocol->state = SILC_PROTOCOL_STATE_START;
623 switch(protocol->state) {
624 case SILC_PROTOCOL_STATE_START:
627 * Start protocol. We send authentication data to the server
628 * to be authenticated.
630 unsigned char *auth_data = NULL;
631 SilcUInt32 auth_data_len = 0;
632 unsigned char sign[2048 + 1];
634 switch(ctx->auth_meth) {
636 /* No authentication required */
639 case SILC_AUTH_PASSWORD:
640 /* Password authentication */
641 if (ctx->auth_data && ctx->auth_data_len) {
642 auth_data = ctx->auth_data;
643 auth_data_len = ctx->auth_data_len;
647 client->internal->ops->say(
648 client, conn, SILC_CLIENT_MESSAGE_INFO,
649 "Password authentication required by server %s",
650 ctx->sock->hostname);
651 client->internal->ops->ask_passphrase(client, conn,
652 silc_client_conn_auth_continue,
657 case SILC_AUTH_PUBLIC_KEY:
658 if (!ctx->auth_data) {
659 /* Public key authentication */
660 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
664 auth_data = ctx->auth_data;
665 auth_data_len = ctx->auth_data_len;
671 silc_client_conn_auth_continue(auth_data,
672 auth_data_len, protocol);
676 case SILC_PROTOCOL_STATE_END:
679 * End protocol. Nothing special to be done here.
682 /* Protocol has ended, call the final callback */
683 if (protocol->final_callback)
684 silc_protocol_execute_final(protocol, client->schedule);
686 silc_protocol_free(protocol);
690 case SILC_PROTOCOL_STATE_ERROR:
693 * Error. Send notify to remote.
695 unsigned char error[4];
697 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
699 /* Error in protocol. Send FAILURE packet. Although I don't think
700 this could ever happen on client side. */
701 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
702 NULL, 0, NULL, NULL, error, 4, TRUE);
704 /* On error the final callback is always called. */
705 if (protocol->final_callback)
706 silc_protocol_execute_final(protocol, client->schedule);
708 silc_protocol_free(protocol);
711 case SILC_PROTOCOL_STATE_FAILURE:
713 * Received failure from remote.
716 /* On error the final callback is always called. */
717 if (protocol->final_callback)
718 silc_protocol_execute_final(protocol, client->schedule);
720 silc_protocol_free(protocol);
723 case SILC_PROTOCOL_STATE_UNKNOWN:
729 * Re-key protocol routines
732 /* Actually takes the new keys into use. */
735 silc_client_protocol_rekey_validate(SilcClient client,
736 SilcClientRekeyInternalContext *ctx,
737 SilcSocketConnection sock,
738 SilcSKEKeyMaterial *keymat,
741 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
743 if (ctx->responder == TRUE) {
745 silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
746 keymat->enc_key_len);
747 silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv);
748 silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
749 keymat->hmac_key_len);
751 silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
752 keymat->enc_key_len);
753 silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv);
754 silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
755 keymat->hmac_key_len);
759 silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
760 keymat->enc_key_len);
761 silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv);
762 silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
763 keymat->hmac_key_len);
765 silc_cipher_set_key(conn->internal->receive_key,
766 keymat->receive_enc_key, keymat->enc_key_len);
767 silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv);
768 silc_hmac_set_key(conn->internal->hmac_receive,
769 keymat->receive_hmac_key, keymat->hmac_key_len);
773 /* Save the current sending encryption key */
775 memset(conn->internal->rekey->send_enc_key, 0,
776 conn->internal->rekey->enc_key_len);
777 silc_free(conn->internal->rekey->send_enc_key);
778 conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
779 keymat->enc_key_len / 8);
780 conn->internal->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->internal->send_key);
795 SilcUInt32 hash_len = silc_hash_len(conn->internal->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->internal->rekey->send_enc_key,
803 conn->internal->rekey->enc_key_len,
804 16, key_len, hash_len,
805 conn->internal->hash, keymat);
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->internal->send_key);
824 SilcUInt32 hash_len = silc_hash_len(conn->internal->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,
837 conn->internal->hash, keymat);
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->internal->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_queue_purge(client, ctx->sock);
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);
946 silc_client_packet_queue_purge(client, ctx->sock);
948 /* The protocol ends in next stage. */
949 protocol->state = SILC_PROTOCOL_STATE_END;
954 * We are the initiator of this protocol
957 /* Start the re-key by sending the REKEY packet */
958 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
959 NULL, 0, NULL, NULL, NULL, 0, FALSE);
961 if (ctx->pfs == TRUE) {
963 * Use Perfect Forward Secrecy, ie. negotiate the key material
964 * using the SKE protocol.
966 ctx->ske = silc_ske_alloc(client->rng, client);
967 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
968 silc_ske_group_get_by_number(conn->internal->rekey->ske_group,
969 &ctx->ske->prop->group);
971 silc_ske_set_callbacks(ctx->ske,
972 silc_client_protocol_rekey_send_packet,
973 NULL, NULL, NULL, silc_ske_check_version,
976 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
977 if (status != SILC_SKE_STATUS_OK) {
978 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
981 protocol->state = SILC_PROTOCOL_STATE_ERROR;
982 silc_protocol_execute(protocol, client->schedule, 0, 300000);
986 /* Advance the protocol state */
990 * Do normal and simple re-key.
993 /* Send the REKEY_DONE to indicate we will take new keys into use
995 silc_client_packet_queue_purge(client, ctx->sock);
996 silc_client_packet_send(client, ctx->sock,
997 SILC_PACKET_REKEY_DONE,
998 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1000 /* After we send REKEY_DONE we must set the sending encryption
1001 key to the new key since all packets after this packet must
1002 encrypted with the new key. */
1003 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1004 silc_client_packet_queue_purge(client, ctx->sock);
1006 /* The protocol ends in next stage. */
1007 protocol->state = SILC_PROTOCOL_STATE_END;
1015 * Second state, used only when oding re-key with PFS.
1017 if (ctx->responder == TRUE) {
1018 if (ctx->pfs == TRUE) {
1020 * Send our KE packe to the initiator now that we've processed
1021 * the initiator's KE packet.
1023 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1024 SILC_SKE_PK_TYPE_SILC);
1026 if (status != SILC_SKE_STATUS_OK) {
1027 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1030 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1031 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1037 if (ctx->pfs == TRUE) {
1039 * The packet type must be KE packet
1041 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1042 /* Error in protocol */
1043 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1044 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1047 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1048 if (status != SILC_SKE_STATUS_OK) {
1049 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1052 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1053 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1059 /* Send the REKEY_DONE to indicate we will take new keys into use
1061 silc_client_packet_queue_purge(client, ctx->sock);
1062 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1063 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1065 /* After we send REKEY_DONE we must set the sending encryption
1066 key to the new key since all packets after this packet must
1067 encrypted with the new key. */
1068 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1069 silc_client_packet_queue_purge(client, ctx->sock);
1071 /* The protocol ends in next stage. */
1072 protocol->state = SILC_PROTOCOL_STATE_END;
1075 case SILC_PROTOCOL_STATE_END:
1080 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1081 /* Error in protocol */
1082 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1083 silc_protocol_execute(protocol, client->schedule, 0, 0);
1086 /* We received the REKEY_DONE packet and all packets after this is
1087 encrypted with the new key so set the decryption key to the new key */
1088 if (ctx->pfs == TRUE)
1089 silc_client_protocol_rekey_generate_pfs(client, ctx, FALSE);
1091 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1092 silc_client_packet_queue_purge(client, ctx->sock);
1094 /* Protocol has ended, call the final callback */
1095 if (protocol->final_callback)
1096 silc_protocol_execute_final(protocol, client->schedule);
1098 silc_protocol_free(protocol);
1101 case SILC_PROTOCOL_STATE_ERROR:
1106 if (ctx->pfs == TRUE) {
1107 /* Send abort notification */
1108 silc_ske_abort(ctx->ske, ctx->ske->status);
1111 /* On error the final callback is always called. */
1112 if (protocol->final_callback)
1113 silc_protocol_execute_final(protocol, client->schedule);
1115 silc_protocol_free(protocol);
1118 case SILC_PROTOCOL_STATE_FAILURE:
1120 * We have received failure from remote
1123 /* On error the final callback is always called. */
1124 if (protocol->final_callback)
1125 silc_protocol_execute_final(protocol, client->schedule);
1127 silc_protocol_free(protocol);
1130 case SILC_PROTOCOL_STATE_UNKNOWN:
1136 /* Registers protocols used in client */
1138 void silc_client_protocols_register(void)
1140 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1141 silc_client_protocol_connection_auth);
1142 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1143 silc_client_protocol_key_exchange);
1144 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1145 silc_client_protocol_rekey);
1148 /* Unregisters protocols */
1150 void silc_client_protocols_unregister(void)
1152 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1153 silc_client_protocol_connection_auth);
1154 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1155 silc_client_protocol_key_exchange);
1156 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1157 silc_client_protocol_rekey);