5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Client side of the protocols.
25 #include "silcincludes.h"
26 #include "silcclient.h"
27 #include "client_internal.h"
29 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
30 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
31 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
34 * Key Exhange protocol functions
37 /* Function that is called when SKE protocol sends packets to network. */
39 void silc_client_protocol_ke_send_packet(SilcSKE ske,
44 SilcProtocol protocol = (SilcProtocol)context;
45 SilcClientKEInternalContext *ctx =
46 (SilcClientKEInternalContext *)protocol->context;
47 SilcClient client = (SilcClient)ctx->client;
49 /* Send the packet immediately */
50 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
51 packet->data, packet->len, TRUE);
54 /* Public key verification callback. Called by the application. */
58 SilcSKEVerifyCbCompletion completion;
59 void *completion_context;
62 static void silc_client_verify_key_cb(bool success, void *context)
64 VerifyKeyContext verify = (VerifyKeyContext)context;
66 SILC_LOG_DEBUG(("Start"));
68 /* Call the completion callback back to the SKE */
69 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
70 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
71 verify->completion_context);
76 /* Callback that is called when we have received KE payload from
77 responder. We try to verify the public key now. */
79 void silc_client_protocol_ke_verify_key(SilcSKE ske,
80 unsigned char *pk_data,
82 SilcSKEPKType pk_type,
84 SilcSKEVerifyCbCompletion completion,
85 void *completion_context)
87 SilcProtocol protocol = (SilcProtocol)context;
88 SilcClientKEInternalContext *ctx =
89 (SilcClientKEInternalContext *)protocol->context;
90 SilcClient client = (SilcClient)ctx->client;
91 VerifyKeyContext verify;
93 SILC_LOG_DEBUG(("Start"));
95 verify = silc_calloc(1, sizeof(*verify));
97 verify->completion = completion;
98 verify->completion_context = completion_context;
100 /* Verify public key from user. */
101 client->internal->ops->verify_public_key(client, ctx->sock->user_data,
103 pk_data, pk_len, pk_type,
104 silc_client_verify_key_cb, verify);
107 /* Sets the negotiated key material into use for particular connection. */
109 void silc_client_protocol_ke_set_keys(SilcSKE ske,
110 SilcSocketConnection sock,
111 SilcSKEKeyMaterial *keymat,
116 SilcSKEDiffieHellmanGroup group,
119 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
121 SILC_LOG_DEBUG(("Setting new keys into use"));
123 /* Allocate cipher to be used in the communication */
124 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
125 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
126 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
127 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
129 if (is_responder == TRUE) {
130 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
131 keymat->enc_key_len);
132 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
133 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
134 keymat->enc_key_len);
135 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
136 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
137 keymat->hmac_key_len);
138 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
139 keymat->hmac_key_len);
141 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
142 keymat->enc_key_len);
143 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
144 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
145 keymat->enc_key_len);
146 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
147 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
148 keymat->hmac_key_len);
149 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
150 keymat->hmac_key_len);
154 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
155 conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
156 keymat->enc_key_len / 8);
157 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
159 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
160 conn->rekey->pfs = TRUE;
161 conn->rekey->ske_group = silc_ske_group_get_number(group);
163 /* Save the HASH function */
164 silc_hash_alloc(hash->hash->name, &conn->hash);
167 /* Checks the version string of the server. */
169 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
170 SilcUInt32 len, void *context)
172 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
173 SilcClient client = (SilcClient)ske->user_data;
174 SilcSKEStatus status = SILC_SKE_STATUS_OK;
176 int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
178 /* Check for initial version string */
179 if (!strstr(version, "SILC-1.0-"))
180 status = SILC_SKE_STATUS_BAD_VERSION;
182 /* Check software version */
186 status = SILC_SKE_STATUS_BAD_VERSION;
189 cp = strchr(cp, '.');
194 cp = strchr(cp, '.');
196 build = atoi(cp + 1);
198 cp = client->internal->silc_client_version + 9;
200 status = SILC_SKE_STATUS_BAD_VERSION;
203 cp = strchr(cp, '.');
208 cp = strchr(cp, '.');
210 build2 = atoi(cp + 1);
213 status = SILC_SKE_STATUS_BAD_VERSION;
215 if (status != SILC_SKE_STATUS_OK)
216 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
217 "We don't support server version `%s'",
223 /* Callback that is called by the SKE to indicate that it is safe to
224 continue the execution of the protocol. Is given as argument to the
225 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
226 This is called due to the fact that the public key verification
227 process is asynchronous and we must not continue the protocl until
228 the public key has been verified and this callback is called. */
230 static void silc_client_protocol_ke_continue(SilcSKE ske,
233 SilcProtocol protocol = (SilcProtocol)context;
234 SilcClientKEInternalContext *ctx =
235 (SilcClientKEInternalContext *)protocol->context;
236 SilcClient client = (SilcClient)ctx->client;
237 SilcClientConnection conn = ctx->sock->user_data;
239 SILC_LOG_DEBUG(("Start"));
241 if (ske->status != SILC_SKE_STATUS_OK) {
242 /* Call failure client operation */
243 client->internal->ops->failure(client, conn, protocol,
244 (void *)ske->status);
245 protocol->state = SILC_PROTOCOL_STATE_ERROR;
246 silc_protocol_execute(protocol, client->schedule, 0, 0);
250 /* Send Ok to the other end. We will end the protocol as server
251 sends Ok to us when we will take the new keys into use. Do this
252 if we are initiator. This is happens when this callback was sent
253 to silc_ske_initiator_finish function. */
254 if (ctx->responder == FALSE) {
255 silc_ske_end(ctx->ske);
257 /* End the protocol on the next round */
258 protocol->state = SILC_PROTOCOL_STATE_END;
261 /* Advance protocol state and call the next state if we are responder.
262 This happens when this callback was sent to silc_ske_responder_phase_2
264 if (ctx->responder == TRUE) {
266 silc_protocol_execute(protocol, client->schedule, 0, 100000);
270 /* Performs key exchange protocol. This is used for both initiator
271 and responder key exchange. This may be called recursively. */
273 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
275 SilcProtocol protocol = (SilcProtocol)context;
276 SilcClientKEInternalContext *ctx =
277 (SilcClientKEInternalContext *)protocol->context;
278 SilcClient client = (SilcClient)ctx->client;
279 SilcClientConnection conn = ctx->sock->user_data;
280 SilcSKEStatus status = SILC_SKE_STATUS_OK;
282 SILC_LOG_DEBUG(("Start"));
284 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
285 protocol->state = SILC_PROTOCOL_STATE_START;
287 switch(protocol->state) {
288 case SILC_PROTOCOL_STATE_START:
295 /* Allocate Key Exchange object */
296 ctx->ske = ske = silc_ske_alloc(client->rng, client);
298 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
300 silc_client_protocol_ke_continue,
301 silc_ske_check_version,
304 if (ctx->responder == TRUE) {
305 /* Start the key exchange by processing the received security
306 properties packet from initiator. */
308 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
309 client->internal->silc_client_version,
310 ctx->packet->buffer, TRUE);
312 SilcSKEStartPayload *start_payload;
314 /* Assemble security properties. */
315 silc_ske_assemble_security_properties(
316 ske, SILC_SKE_SP_FLAG_MUTUAL,
317 client->internal->silc_client_version,
320 /* Start the key exchange by sending our security properties
321 to the remote end. */
322 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
326 /* Return now if the procedure is pending */
327 if (status == SILC_SKE_STATUS_PENDING)
330 if (status != SILC_SKE_STATUS_OK) {
331 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
333 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
336 protocol->state = SILC_PROTOCOL_STATE_ERROR;
337 silc_protocol_execute(protocol, client->schedule, 0, 0);
341 /* Advance protocol state and call the next state if we are responder */
343 if (ctx->responder == TRUE)
344 silc_protocol_execute(protocol, client->schedule, 0, 100000);
352 if (ctx->responder == TRUE) {
353 /* Sends the selected security properties to the initiator. */
354 status = silc_ske_responder_phase_1(ctx->ske);
356 /* Call Phase-1 function. This processes the Key Exchange Start
357 paylaod reply we just got from the responder. The callback
358 function will receive the processed payload where we will
360 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
363 if (status != SILC_SKE_STATUS_OK) {
364 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
366 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
369 protocol->state = SILC_PROTOCOL_STATE_ERROR;
370 silc_protocol_execute(protocol, client->schedule, 0, 0);
374 /* Advance protocol state and call next state if we are initiator */
376 if (ctx->responder == FALSE)
377 silc_protocol_execute(protocol, client->schedule, 0, 100000);
385 if (ctx->responder == TRUE) {
386 /* Process the received Key Exchange 1 Payload packet from
387 the initiator. This also creates our parts of the Diffie
388 Hellman algorithm. The silc_client_protocol_ke_continue will
389 be called after the public key has been verified. */
390 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
392 /* Call the Phase-2 function. This creates Diffie Hellman
393 key exchange parameters and sends our public part inside
394 Key Exhange 1 Payload to the responder. */
395 status = silc_ske_initiator_phase_2(ctx->ske,
398 SILC_SKE_PK_TYPE_SILC);
402 /* Return now if the procedure is pending */
403 if (status == SILC_SKE_STATUS_PENDING)
406 if (status != SILC_SKE_STATUS_OK) {
407 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
409 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
412 protocol->state = SILC_PROTOCOL_STATE_ERROR;
413 silc_protocol_execute(protocol, client->schedule, 0, 0);
423 if (ctx->responder == TRUE) {
424 /* This creates the key exchange material and sends our
425 public parts to the initiator inside Key Exchange 2 Payload. */
427 silc_ske_responder_finish(ctx->ske,
428 client->public_key, client->private_key,
429 SILC_SKE_PK_TYPE_SILC);
431 /* End the protocol on the next round */
432 protocol->state = SILC_PROTOCOL_STATE_END;
434 /* Finish the protocol. This verifies the Key Exchange 2 payload
435 sent by responder. The silc_client_protocol_ke_continue will
436 be called after the public key has been verified. */
437 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
440 /* Return now if the procedure is pending */
441 if (status == SILC_SKE_STATUS_PENDING)
444 if (status != SILC_SKE_STATUS_OK) {
445 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
446 client->internal->ops->say(
447 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
448 "Received unsupported server %s public key",
449 ctx->sock->hostname);
451 client->internal->ops->say(
452 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
453 "Error during key exchange protocol with server %s",
454 ctx->sock->hostname);
456 protocol->state = SILC_PROTOCOL_STATE_ERROR;
457 silc_protocol_execute(protocol, client->schedule, 0, 0);
463 case SILC_PROTOCOL_STATE_END:
468 SilcSKEKeyMaterial *keymat;
469 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
470 int hash_len = ctx->ske->prop->hash->hash->hash_len;
472 /* Process the key material */
473 keymat = silc_calloc(1, sizeof(*keymat));
474 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
476 if (status != SILC_SKE_STATUS_OK) {
477 protocol->state = SILC_PROTOCOL_STATE_ERROR;
478 silc_protocol_execute(protocol, client->schedule, 0, 300000);
479 silc_ske_free_key_material(keymat);
482 ctx->keymat = keymat;
484 /* Send Ok to the other end if we are responder. If we are initiator
485 we have sent this already. */
486 if (ctx->responder == TRUE)
487 silc_ske_end(ctx->ske);
489 /* Unregister the timeout task since the protocol has ended.
490 This was the timeout task to be executed if the protocol is
491 not completed fast enough. */
492 if (ctx->timeout_task)
493 silc_schedule_task_del(client->schedule, ctx->timeout_task);
495 /* Protocol has ended, call the final callback */
496 if (protocol->final_callback)
497 silc_protocol_execute_final(protocol, client->schedule);
499 silc_protocol_free(protocol);
503 case SILC_PROTOCOL_STATE_ERROR:
505 * Error during protocol
508 /* Send abort notification */
509 silc_ske_abort(ctx->ske, ctx->ske->status);
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);
518 case SILC_PROTOCOL_STATE_FAILURE:
520 * Received failure from remote.
523 /* Unregister the timeout task since the protocol has ended.
524 This was the timeout task to be executed if the protocol is
525 not completed fast enough. */
526 if (ctx->timeout_task)
527 silc_schedule_task_del(client->schedule, ctx->timeout_task);
529 /* On error the final callback is always called. */
530 if (protocol->final_callback)
531 silc_protocol_execute_final(protocol, client->schedule);
533 silc_protocol_free(protocol);
535 case SILC_PROTOCOL_STATE_UNKNOWN:
541 * Connection Authentication protocol functions
545 silc_client_get_public_key_auth(SilcClient client,
546 SilcClientConnection conn,
547 unsigned char *auth_data,
548 SilcUInt32 *auth_data_len,
555 /* Use our default key */
558 /* Make the authentication data. Protocol says it is HASH plus
560 len = ske->hash_len + ske->start_payload_copy->len;
561 auth = silc_buffer_alloc(len);
562 silc_buffer_pull_tail(auth, len);
563 silc_buffer_format(auth,
564 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
565 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
566 ske->start_payload_copy->len),
569 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
570 auth->len, auth_data, auth_data_len)) {
571 silc_buffer_free(auth);
575 silc_buffer_free(auth);
579 /* Continues the connection authentication protocol. This funtion may
580 be called directly or used as SilcAskPassphrase callback. */
583 silc_client_conn_auth_continue(unsigned char *auth_data,
584 SilcUInt32 auth_data_len, void *context)
586 SilcProtocol protocol = (SilcProtocol)context;
587 SilcClientConnAuthInternalContext *ctx =
588 (SilcClientConnAuthInternalContext *)protocol->context;
589 SilcClient client = (SilcClient)ctx->client;
593 SILC_LOG_DEBUG(("Start"));
595 payload_len = 4 + auth_data_len;
596 packet = silc_buffer_alloc(payload_len);
597 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
598 silc_buffer_format(packet,
599 SILC_STR_UI_SHORT(payload_len),
600 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
601 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
604 /* Send the packet to server */
605 silc_client_packet_send(client, ctx->sock,
606 SILC_PACKET_CONNECTION_AUTH,
608 packet->data, packet->len, TRUE);
609 silc_buffer_free(packet);
611 /* Next state is end of protocol */
612 protocol->state = SILC_PROTOCOL_STATE_END;
615 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
617 SilcProtocol protocol = (SilcProtocol)context;
618 SilcClientConnAuthInternalContext *ctx =
619 (SilcClientConnAuthInternalContext *)protocol->context;
620 SilcClient client = (SilcClient)ctx->client;
621 SilcClientConnection conn = ctx->sock->user_data;
623 SILC_LOG_DEBUG(("Start"));
625 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
626 protocol->state = SILC_PROTOCOL_STATE_START;
628 switch(protocol->state) {
629 case SILC_PROTOCOL_STATE_START:
632 * Start protocol. We send authentication data to the server
633 * to be authenticated.
635 unsigned char *auth_data = NULL;
636 SilcUInt32 auth_data_len = 0;
637 unsigned char sign[1024];
639 switch(ctx->auth_meth) {
641 /* No authentication required */
644 case SILC_AUTH_PASSWORD:
645 /* Password authentication */
646 if (ctx->auth_data && ctx->auth_data_len) {
647 auth_data = ctx->auth_data;
648 auth_data_len = ctx->auth_data_len;
652 client->internal->ops->say(
653 client, conn, SILC_CLIENT_MESSAGE_INFO,
654 "Password authentication required by server %s",
655 ctx->sock->hostname);
656 client->internal->ops->ask_passphrase(client, conn,
657 silc_client_conn_auth_continue,
662 case SILC_AUTH_PUBLIC_KEY:
663 if (!ctx->auth_data) {
664 /* Public key authentication */
665 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
669 auth_data = ctx->auth_data;
670 auth_data_len = ctx->auth_data_len;
676 silc_client_conn_auth_continue(auth_data,
677 auth_data_len, protocol);
681 case SILC_PROTOCOL_STATE_END:
684 * End protocol. Nothing special to be done here.
687 /* Protocol has ended, call the final callback */
688 if (protocol->final_callback)
689 silc_protocol_execute_final(protocol, client->schedule);
691 silc_protocol_free(protocol);
695 case SILC_PROTOCOL_STATE_ERROR:
698 * Error. Send notify to remote.
700 unsigned char error[4];
702 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
704 /* Error in protocol. Send FAILURE packet. Although I don't think
705 this could ever happen on client side. */
706 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
707 NULL, 0, NULL, NULL, error, 4, TRUE);
709 /* On error the final callback is always called. */
710 if (protocol->final_callback)
711 silc_protocol_execute_final(protocol, client->schedule);
713 silc_protocol_free(protocol);
716 case SILC_PROTOCOL_STATE_FAILURE:
718 * Received failure from remote.
721 /* On error the final callback is always called. */
722 if (protocol->final_callback)
723 silc_protocol_execute_final(protocol, client->schedule);
725 silc_protocol_free(protocol);
728 case SILC_PROTOCOL_STATE_UNKNOWN:
734 * Re-key protocol routines
737 /* Actually takes the new keys into use. */
740 silc_client_protocol_rekey_validate(SilcClient client,
741 SilcClientRekeyInternalContext *ctx,
742 SilcSocketConnection sock,
743 SilcSKEKeyMaterial *keymat,
746 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
748 if (ctx->responder == TRUE) {
750 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
751 keymat->enc_key_len);
752 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
753 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
754 keymat->hmac_key_len);
756 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
757 keymat->enc_key_len);
758 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
759 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
760 keymat->hmac_key_len);
764 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
765 keymat->enc_key_len);
766 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
767 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
768 keymat->hmac_key_len);
770 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
771 keymat->enc_key_len);
772 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
773 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
774 keymat->hmac_key_len);
778 /* Save the current sending encryption key */
780 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
781 silc_free(conn->rekey->send_enc_key);
782 conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
783 keymat->enc_key_len / 8);
784 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
788 /* This function actually re-generates (when not using PFS) the keys and
789 takes them into use. */
792 silc_client_protocol_rekey_generate(SilcClient client,
793 SilcClientRekeyInternalContext *ctx,
796 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
797 SilcSKEKeyMaterial *keymat;
798 SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
799 SilcUInt32 hash_len = conn->hash->hash->hash_len;
801 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
802 send ? "sending" : "receiving"));
804 /* Generate the new key */
805 keymat = silc_calloc(1, sizeof(*keymat));
806 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
807 conn->rekey->enc_key_len,
808 16, key_len, hash_len,
811 /* Set the keys into use */
812 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
814 silc_ske_free_key_material(keymat);
817 /* This function actually re-generates (with PFS) the keys and
818 takes them into use. */
821 silc_client_protocol_rekey_generate_pfs(SilcClient client,
822 SilcClientRekeyInternalContext *ctx,
825 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
826 SilcSKEKeyMaterial *keymat;
827 SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
828 SilcUInt32 hash_len = conn->hash->hash->hash_len;
829 unsigned char *tmpbuf;
832 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
833 send ? "sending" : "receiving"));
835 /* Encode KEY to binary data */
836 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
838 /* Generate the new key */
839 keymat = silc_calloc(1, sizeof(*keymat));
840 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
843 /* Set the keys into use */
844 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
846 memset(tmpbuf, 0, klen);
848 silc_ske_free_key_material(keymat);
851 /* Packet sending callback. This function is provided as packet sending
852 routine to the Key Exchange functions. */
855 silc_client_protocol_rekey_send_packet(SilcSKE ske,
860 SilcProtocol protocol = (SilcProtocol)context;
861 SilcClientRekeyInternalContext *ctx =
862 (SilcClientRekeyInternalContext *)protocol->context;
863 SilcClient client = (SilcClient)ctx->client;
865 /* Send the packet immediately */
866 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
867 packet->data, packet->len, FALSE);
870 /* Performs re-key as defined in the SILC protocol specification. */
872 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
874 SilcProtocol protocol = (SilcProtocol)context;
875 SilcClientRekeyInternalContext *ctx =
876 (SilcClientRekeyInternalContext *)protocol->context;
877 SilcClient client = (SilcClient)ctx->client;
878 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
879 SilcSKEStatus status;
881 SILC_LOG_DEBUG(("Start"));
883 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
884 protocol->state = SILC_PROTOCOL_STATE_START;
886 SILC_LOG_DEBUG(("State=%d", protocol->state));
888 switch(protocol->state) {
889 case SILC_PROTOCOL_STATE_START:
895 if (ctx->responder == TRUE) {
897 * We are receiving party
900 if (ctx->pfs == TRUE) {
902 * Use Perfect Forward Secrecy, ie. negotiate the key material
903 * using the SKE protocol.
906 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
907 /* Error in protocol */
908 protocol->state = SILC_PROTOCOL_STATE_ERROR;
909 silc_protocol_execute(protocol, client->schedule, 0, 300000);
912 ctx->ske = silc_ske_alloc(client->rng, client);
913 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
914 silc_ske_group_get_by_number(conn->rekey->ske_group,
915 &ctx->ske->prop->group);
917 silc_ske_set_callbacks(ctx->ske,
918 silc_client_protocol_rekey_send_packet,
919 NULL, NULL, NULL, silc_ske_check_version,
922 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
923 if (status != SILC_SKE_STATUS_OK) {
924 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
927 protocol->state = SILC_PROTOCOL_STATE_ERROR;
928 silc_protocol_execute(protocol, client->schedule, 0, 300000);
932 /* Advance the protocol state */
934 silc_protocol_execute(protocol, client->schedule, 0, 0);
937 * Do normal and simple re-key.
940 /* Send the REKEY_DONE to indicate we will take new keys into use */
941 silc_client_packet_send(client, ctx->sock,
942 SILC_PACKET_REKEY_DONE,
943 NULL, 0, NULL, NULL, NULL, 0, FALSE);
945 /* After we send REKEY_DONE we must set the sending encryption
946 key to the new key since all packets after this packet must
947 encrypted with the new key. */
948 silc_client_protocol_rekey_generate(client, ctx, TRUE);
950 /* The protocol ends in next stage. */
951 protocol->state = SILC_PROTOCOL_STATE_END;
956 * We are the initiator of this protocol
959 /* Start the re-key by sending the REKEY packet */
960 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
961 NULL, 0, NULL, NULL, NULL, 0, FALSE);
963 if (ctx->pfs == TRUE) {
965 * Use Perfect Forward Secrecy, ie. negotiate the key material
966 * using the SKE protocol.
968 ctx->ske = silc_ske_alloc(client->rng, client);
969 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
970 silc_ske_group_get_by_number(conn->rekey->ske_group,
971 &ctx->ske->prop->group);
973 silc_ske_set_callbacks(ctx->ske,
974 silc_client_protocol_rekey_send_packet,
975 NULL, NULL, NULL, silc_ske_check_version,
978 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
979 if (status != SILC_SKE_STATUS_OK) {
980 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
983 protocol->state = SILC_PROTOCOL_STATE_ERROR;
984 silc_protocol_execute(protocol, client->schedule, 0, 300000);
988 /* Advance the protocol state */
992 * Do normal and simple re-key.
995 /* Send the REKEY_DONE to indicate we will take new keys into use
997 silc_client_packet_send(client, ctx->sock,
998 SILC_PACKET_REKEY_DONE,
999 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1001 /* After we send REKEY_DONE we must set the sending encryption
1002 key to the new key since all packets after this packet must
1003 encrypted with the new key. */
1004 silc_client_protocol_rekey_generate(client, ctx, TRUE);
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_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1062 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1064 /* After we send REKEY_DONE we must set the sending encryption
1065 key to the new key since all packets after this packet must
1066 encrypted with the new key. */
1067 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1069 /* The protocol ends in next stage. */
1070 protocol->state = SILC_PROTOCOL_STATE_END;
1073 case SILC_PROTOCOL_STATE_END:
1078 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1079 /* Error in protocol */
1080 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1081 silc_protocol_execute(protocol, client->schedule, 0, 0);
1084 /* We received the REKEY_DONE packet and all packets after this is
1085 encrypted with the new key so set the decryption key to the new key */
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);