5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Client side of the protocols.
25 #include "clientlibincludes.h"
26 #include "client_internal.h"
28 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
29 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
30 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
33 * Key Exhange protocol functions
36 /* Function that is called when SKE protocol sends packets to network. */
38 void silc_client_protocol_ke_send_packet(SilcSKE ske,
43 SilcProtocol protocol = (SilcProtocol)context;
44 SilcClientKEInternalContext *ctx =
45 (SilcClientKEInternalContext *)protocol->context;
46 SilcClient client = (SilcClient)ctx->client;
48 /* Send the packet immediately */
49 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
50 packet->data, packet->len, TRUE);
53 /* Public key verification callback. Called by the application. */
57 SilcSKEVerifyCbCompletion completion;
58 void *completion_context;
61 static void silc_client_verify_key_cb(bool success, void *context)
63 VerifyKeyContext verify = (VerifyKeyContext)context;
65 SILC_LOG_DEBUG(("Start"));
67 /* Call the completion callback back to the SKE */
68 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
69 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
70 verify->completion_context);
75 /* Callback that is called when we have received KE payload from
76 responder. We try to verify the public key now. */
78 void silc_client_protocol_ke_verify_key(SilcSKE ske,
79 unsigned char *pk_data,
81 SilcSKEPKType pk_type,
83 SilcSKEVerifyCbCompletion completion,
84 void *completion_context)
86 SilcProtocol protocol = (SilcProtocol)context;
87 SilcClientKEInternalContext *ctx =
88 (SilcClientKEInternalContext *)protocol->context;
89 SilcClient client = (SilcClient)ctx->client;
90 VerifyKeyContext verify;
92 SILC_LOG_DEBUG(("Start"));
94 verify = silc_calloc(1, sizeof(*verify));
96 verify->completion = completion;
97 verify->completion_context = completion_context;
99 /* Verify public key from user. */
100 client->ops->verify_public_key(client, ctx->sock->user_data,
102 pk_data, pk_len, pk_type,
103 silc_client_verify_key_cb, verify);
106 /* Sets the negotiated key material into use for particular connection. */
108 void silc_client_protocol_ke_set_keys(SilcSKE ske,
109 SilcSocketConnection sock,
110 SilcSKEKeyMaterial *keymat,
115 SilcSKEDiffieHellmanGroup group,
118 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
120 SILC_LOG_DEBUG(("Setting new keys into use"));
122 /* Allocate cipher to be used in the communication */
123 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
124 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
125 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
126 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
128 if (is_responder == TRUE) {
129 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
130 keymat->enc_key_len);
131 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
132 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
133 keymat->enc_key_len);
134 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
135 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
136 keymat->hmac_key_len);
137 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
138 keymat->hmac_key_len);
140 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
141 keymat->enc_key_len);
142 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
143 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
144 keymat->enc_key_len);
145 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
146 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
147 keymat->hmac_key_len);
148 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
149 keymat->hmac_key_len);
153 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
154 conn->rekey->send_enc_key =
155 silc_calloc(keymat->enc_key_len / 8,
156 sizeof(*conn->rekey->send_enc_key));
157 memcpy(conn->rekey->send_enc_key,
158 keymat->send_enc_key, keymat->enc_key_len / 8);
159 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
161 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
162 conn->rekey->pfs = TRUE;
163 conn->rekey->ske_group = silc_ske_group_get_number(group);
165 /* Save the HASH function */
166 silc_hash_alloc(hash->hash->name, &conn->hash);
169 /* Checks the version string of the server. */
171 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
172 uint32 len, void *context)
174 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
175 SilcClient client = (SilcClient)ske->user_data;
176 SilcSKEStatus status = SILC_SKE_STATUS_OK;
178 int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
180 /* Check for initial version string */
181 if (!strstr(version, "SILC-1.0-"))
182 status = SILC_SKE_STATUS_BAD_VERSION;
184 /* Check software version */
188 status = SILC_SKE_STATUS_BAD_VERSION;
191 cp = strchr(cp, '.');
196 cp = strchr(cp, '.');
198 build = atoi(cp + 1);
200 cp = client->silc_client_version + 9;
202 status = SILC_SKE_STATUS_BAD_VERSION;
205 cp = strchr(cp, '.');
210 cp = strchr(cp, '.');
212 build2 = atoi(cp + 1);
215 status = SILC_SKE_STATUS_BAD_VERSION;
217 status = SILC_SKE_STATUS_BAD_VERSION;
219 if (status != SILC_SKE_STATUS_OK)
220 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
221 "We don't support server version `%s'", version);
226 /* Callback that is called by the SKE to indicate that it is safe to
227 continue the execution of the protocol. Is given as argument to the
228 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
229 This is called due to the fact that the public key verification
230 process is asynchronous and we must not continue the protocl until
231 the public key has been verified and this callback is called. */
233 static void silc_client_protocol_ke_continue(SilcSKE ske,
236 SilcProtocol protocol = (SilcProtocol)context;
237 SilcClientKEInternalContext *ctx =
238 (SilcClientKEInternalContext *)protocol->context;
239 SilcClient client = (SilcClient)ctx->client;
240 SilcClientConnection conn = ctx->sock->user_data;
242 SILC_LOG_DEBUG(("Start"));
244 if (ske->status != SILC_SKE_STATUS_OK) {
245 if (ske->status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
246 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
247 "Received unsupported server %s public key",
248 ctx->sock->hostname);
249 } else if (ske->status == SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED) {
250 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
251 "Remote host did not send its public key, even though "
254 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
255 "Error during key exchange protocol with server %s",
256 ctx->sock->hostname);
259 protocol->state = SILC_PROTOCOL_STATE_ERROR;
260 silc_protocol_execute(protocol, client->schedule, 0, 0);
264 /* Send Ok to the other end. We will end the protocol as server
265 sends Ok to us when we will take the new keys into use. Do this
266 if we are initiator. This is happens when this callback was sent
267 to silc_ske_initiator_finish function. */
268 if (ctx->responder == FALSE) {
269 silc_ske_end(ctx->ske);
271 /* End the protocol on the next round */
272 protocol->state = SILC_PROTOCOL_STATE_END;
275 /* Advance protocol state and call the next state if we are responder.
276 This happens when this callback was sent to silc_ske_responder_phase_2
278 if (ctx->responder == TRUE) {
280 silc_protocol_execute(protocol, client->schedule, 0, 100000);
284 /* Performs key exchange protocol. This is used for both initiator
285 and responder key exchange. This may be called recursively. */
287 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
289 SilcProtocol protocol = (SilcProtocol)context;
290 SilcClientKEInternalContext *ctx =
291 (SilcClientKEInternalContext *)protocol->context;
292 SilcClient client = (SilcClient)ctx->client;
293 SilcClientConnection conn = ctx->sock->user_data;
294 SilcSKEStatus status = SILC_SKE_STATUS_OK;
296 SILC_LOG_DEBUG(("Start"));
298 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
299 protocol->state = SILC_PROTOCOL_STATE_START;
301 switch(protocol->state) {
302 case SILC_PROTOCOL_STATE_START:
309 /* Allocate Key Exchange object */
310 ske = silc_ske_alloc();
312 ske->rng = client->rng;
313 ske->user_data = (void *)client;
315 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
317 silc_client_protocol_ke_continue,
318 silc_ske_check_version,
321 if (ctx->responder == TRUE) {
322 /* Start the key exchange by processing the received security
323 properties packet from initiator. */
324 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
325 client->silc_client_version,
326 ctx->packet->buffer, TRUE);
328 SilcSKEStartPayload *start_payload;
330 /* Assemble security properties. */
331 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
332 client->silc_client_version,
335 /* Start the key exchange by sending our security properties
336 to the remote end. */
337 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
341 /* Return now if the procedure is pending */
342 if (status == SILC_SKE_STATUS_PENDING)
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 the next state if we are responder */
358 if (ctx->responder == TRUE)
359 silc_protocol_execute(protocol, client->schedule, 0, 100000);
367 if (ctx->responder == TRUE) {
368 /* Sends the selected security properties to the initiator. */
370 silc_ske_responder_phase_1(ctx->ske,
371 ctx->ske->start_payload);
373 /* Call Phase-1 function. This processes the Key Exchange Start
374 paylaod reply we just got from the responder. The callback
375 function will receive the processed payload where we will
377 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
380 if (status != SILC_SKE_STATUS_OK) {
381 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
383 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
386 protocol->state = SILC_PROTOCOL_STATE_ERROR;
387 silc_protocol_execute(protocol, client->schedule, 0, 0);
391 /* Advance protocol state and call next state if we are initiator */
393 if (ctx->responder == FALSE)
394 silc_protocol_execute(protocol, client->schedule, 0, 100000);
402 if (ctx->responder == TRUE) {
403 /* Process the received Key Exchange 1 Payload packet from
404 the initiator. This also creates our parts of the Diffie
405 Hellman algorithm. The silc_client_protocol_ke_continue will
406 be called after the public key has been verified. */
407 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
409 /* Call the Phase-2 function. This creates Diffie Hellman
410 key exchange parameters and sends our public part inside
411 Key Exhange 1 Payload to the responder. */
412 status = silc_ske_initiator_phase_2(ctx->ske,
414 client->private_key);
418 /* Return now if the procedure is pending */
419 if (status == SILC_SKE_STATUS_PENDING)
422 if (status != SILC_SKE_STATUS_OK) {
423 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
425 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
428 protocol->state = SILC_PROTOCOL_STATE_ERROR;
429 silc_protocol_execute(protocol, client->schedule, 0, 0);
439 if (ctx->responder == TRUE) {
440 /* This creates the key exchange material and sends our
441 public parts to the initiator inside Key Exchange 2 Payload. */
443 silc_ske_responder_finish(ctx->ske,
444 client->public_key, client->private_key,
445 SILC_SKE_PK_TYPE_SILC);
447 /* End the protocol on the next round */
448 protocol->state = SILC_PROTOCOL_STATE_END;
450 /* Finish the protocol. This verifies the Key Exchange 2 payload
451 sent by responder. The silc_client_protocol_ke_continue will
452 be called after the public key has been verified. */
453 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
456 /* Return now if the procedure is pending */
457 if (status == SILC_SKE_STATUS_PENDING)
460 if (status != SILC_SKE_STATUS_OK) {
461 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
462 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
463 "Received unsupported server %s public key",
464 ctx->sock->hostname);
466 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
467 "Error during key exchange protocol with server %s",
468 ctx->sock->hostname);
470 protocol->state = SILC_PROTOCOL_STATE_ERROR;
471 silc_protocol_execute(protocol, client->schedule, 0, 0);
477 case SILC_PROTOCOL_STATE_END:
482 SilcSKEKeyMaterial *keymat;
483 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
484 int hash_len = ctx->ske->prop->hash->hash->hash_len;
486 /* Process the key material */
487 keymat = silc_calloc(1, sizeof(*keymat));
488 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
490 if (status != SILC_SKE_STATUS_OK) {
491 protocol->state = SILC_PROTOCOL_STATE_ERROR;
492 silc_protocol_execute(protocol, client->schedule, 0, 300000);
493 silc_ske_free_key_material(keymat);
496 ctx->keymat = keymat;
498 /* Send Ok to the other end if we are responder. If we are initiator
499 we have sent this already. */
500 if (ctx->responder == TRUE)
501 silc_ske_end(ctx->ske);
503 /* Unregister the timeout task since the protocol has ended.
504 This was the timeout task to be executed if the protocol is
505 not completed fast enough. */
506 if (ctx->timeout_task)
507 silc_schedule_task_del(client->schedule, ctx->timeout_task);
509 /* Protocol has ended, call the final callback */
510 if (protocol->final_callback)
511 silc_protocol_execute_final(protocol, client->schedule);
513 silc_protocol_free(protocol);
517 case SILC_PROTOCOL_STATE_ERROR:
519 * Error during protocol
522 /* Send abort notification */
523 silc_ske_abort(ctx->ske, ctx->ske->status);
525 /* On error the final callback is always called. */
526 if (protocol->final_callback)
527 silc_protocol_execute_final(protocol, client->schedule);
529 silc_protocol_free(protocol);
532 case SILC_PROTOCOL_STATE_FAILURE:
534 * Received failure from remote.
537 /* Unregister the timeout task since the protocol has ended.
538 This was the timeout task to be executed if the protocol is
539 not completed fast enough. */
540 if (ctx->timeout_task)
541 silc_schedule_task_del(client->schedule, ctx->timeout_task);
543 /* On error the final callback is always called. */
544 if (protocol->final_callback)
545 silc_protocol_execute_final(protocol, client->schedule);
547 silc_protocol_free(protocol);
549 case SILC_PROTOCOL_STATE_UNKNOWN:
555 * Connection Authentication protocol functions
559 silc_client_get_public_key_auth(SilcClient client,
560 SilcClientConnection conn,
561 unsigned char *auth_data,
562 uint32 *auth_data_len,
569 /* Use our default key */
572 /* Make the authentication data. Protocol says it is HASH plus
574 len = ske->hash_len + ske->start_payload_copy->len;
575 auth = silc_buffer_alloc(len);
576 silc_buffer_pull_tail(auth, len);
577 silc_buffer_format(auth,
578 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
579 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
580 ske->start_payload_copy->len),
583 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
584 auth->len, auth_data, auth_data_len)) {
585 silc_buffer_free(auth);
589 silc_buffer_free(auth);
593 /* Continues the connection authentication protocol. This funtion may
594 be called directly or used as SilcAskPassphrase callback. */
597 silc_client_conn_auth_continue(unsigned char *auth_data,
598 uint32 auth_data_len, void *context)
600 SilcProtocol protocol = (SilcProtocol)context;
601 SilcClientConnAuthInternalContext *ctx =
602 (SilcClientConnAuthInternalContext *)protocol->context;
603 SilcClient client = (SilcClient)ctx->client;
607 SILC_LOG_DEBUG(("Start"));
609 payload_len = 4 + auth_data_len;
610 packet = silc_buffer_alloc(payload_len);
611 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
612 silc_buffer_format(packet,
613 SILC_STR_UI_SHORT(payload_len),
614 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
615 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
618 /* Send the packet to server */
619 silc_client_packet_send(client, ctx->sock,
620 SILC_PACKET_CONNECTION_AUTH,
622 packet->data, packet->len, TRUE);
623 silc_buffer_free(packet);
625 /* Next state is end of protocol */
626 protocol->state = SILC_PROTOCOL_STATE_END;
629 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
631 SilcProtocol protocol = (SilcProtocol)context;
632 SilcClientConnAuthInternalContext *ctx =
633 (SilcClientConnAuthInternalContext *)protocol->context;
634 SilcClient client = (SilcClient)ctx->client;
635 SilcClientConnection conn = ctx->sock->user_data;
637 SILC_LOG_DEBUG(("Start"));
639 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
640 protocol->state = SILC_PROTOCOL_STATE_START;
642 switch(protocol->state) {
643 case SILC_PROTOCOL_STATE_START:
646 * Start protocol. We send authentication data to the server
647 * to be authenticated.
649 unsigned char *auth_data = NULL;
650 uint32 auth_data_len = 0;
651 unsigned char sign[1024];
653 switch(ctx->auth_meth) {
655 /* No authentication required */
658 case SILC_AUTH_PASSWORD:
659 /* Password authentication */
660 if (ctx->auth_data && ctx->auth_data_len) {
661 auth_data = ctx->auth_data;
662 auth_data_len = ctx->auth_data_len;
666 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO,
667 "Password authentication required by server %s",
668 ctx->sock->hostname);
669 client->ops->ask_passphrase(client, conn,
670 silc_client_conn_auth_continue,
675 case SILC_AUTH_PUBLIC_KEY:
676 if (!ctx->auth_data) {
677 /* Public key authentication */
678 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
682 auth_data = ctx->auth_data;
683 auth_data_len = ctx->auth_data_len;
689 silc_client_conn_auth_continue(auth_data,
690 auth_data_len, protocol);
694 case SILC_PROTOCOL_STATE_END:
697 * End protocol. Nothing special to be done here.
700 /* Protocol has ended, call the final callback */
701 if (protocol->final_callback)
702 silc_protocol_execute_final(protocol, client->schedule);
704 silc_protocol_free(protocol);
708 case SILC_PROTOCOL_STATE_ERROR:
711 * Error. Send notify to remote.
713 unsigned char error[4];
715 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
717 /* Error in protocol. Send FAILURE packet. Although I don't think
718 this could ever happen on client side. */
719 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
720 NULL, 0, NULL, NULL, error, 4, TRUE);
722 /* On error the final callback is always called. */
723 if (protocol->final_callback)
724 silc_protocol_execute_final(protocol, client->schedule);
726 silc_protocol_free(protocol);
729 case SILC_PROTOCOL_STATE_FAILURE:
731 * Received failure from remote.
734 /* On error the final callback is always called. */
735 if (protocol->final_callback)
736 silc_protocol_execute_final(protocol, client->schedule);
738 silc_protocol_free(protocol);
741 case SILC_PROTOCOL_STATE_UNKNOWN:
747 * Re-key protocol routines
750 /* Actually takes the new keys into use. */
753 silc_client_protocol_rekey_validate(SilcClient client,
754 SilcClientRekeyInternalContext *ctx,
755 SilcSocketConnection sock,
756 SilcSKEKeyMaterial *keymat,
759 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
761 if (ctx->responder == TRUE) {
763 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
764 keymat->enc_key_len);
765 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
766 silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key,
767 keymat->hmac_key_len);
769 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
770 keymat->enc_key_len);
771 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
772 silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key,
773 keymat->hmac_key_len);
777 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
778 keymat->enc_key_len);
779 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
780 silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key,
781 keymat->hmac_key_len);
783 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
784 keymat->enc_key_len);
785 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
786 silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key,
787 keymat->hmac_key_len);
791 /* Save the current sending encryption key */
793 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
794 silc_free(conn->rekey->send_enc_key);
795 conn->rekey->send_enc_key =
796 silc_calloc(keymat->enc_key_len / 8,
797 sizeof(*conn->rekey->send_enc_key));
798 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
799 keymat->enc_key_len / 8);
800 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
804 /* This function actually re-generates (when not using PFS) the keys and
805 takes them into use. */
808 silc_client_protocol_rekey_generate(SilcClient client,
809 SilcClientRekeyInternalContext *ctx,
812 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
813 SilcSKEKeyMaterial *keymat;
814 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
815 uint32 hash_len = conn->hash->hash->hash_len;
817 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
818 send ? "sending" : "receiving"));
820 /* Generate the new key */
821 keymat = silc_calloc(1, sizeof(*keymat));
822 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
823 conn->rekey->enc_key_len,
824 16, key_len, hash_len,
827 /* Set the keys into use */
828 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
830 silc_ske_free_key_material(keymat);
833 /* This function actually re-generates (with PFS) the keys and
834 takes them into use. */
837 silc_client_protocol_rekey_generate_pfs(SilcClient client,
838 SilcClientRekeyInternalContext *ctx,
841 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
842 SilcSKEKeyMaterial *keymat;
843 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
844 uint32 hash_len = conn->hash->hash->hash_len;
845 unsigned char *tmpbuf;
848 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
849 send ? "sending" : "receiving"));
851 /* Encode KEY to binary data */
852 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
854 /* Generate the new key */
855 keymat = silc_calloc(1, sizeof(*keymat));
856 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
859 /* Set the keys into use */
860 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
862 memset(tmpbuf, 0, klen);
864 silc_ske_free_key_material(keymat);
867 /* Packet sending callback. This function is provided as packet sending
868 routine to the Key Exchange functions. */
871 silc_client_protocol_rekey_send_packet(SilcSKE ske,
876 SilcProtocol protocol = (SilcProtocol)context;
877 SilcClientRekeyInternalContext *ctx =
878 (SilcClientRekeyInternalContext *)protocol->context;
879 SilcClient client = (SilcClient)ctx->client;
881 /* Send the packet immediately */
882 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
883 packet->data, packet->len, FALSE);
886 /* Performs re-key as defined in the SILC protocol specification. */
888 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
890 SilcProtocol protocol = (SilcProtocol)context;
891 SilcClientRekeyInternalContext *ctx =
892 (SilcClientRekeyInternalContext *)protocol->context;
893 SilcClient client = (SilcClient)ctx->client;
894 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
895 SilcSKEStatus status;
897 SILC_LOG_DEBUG(("Start"));
899 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
900 protocol->state = SILC_PROTOCOL_STATE_START;
902 SILC_LOG_DEBUG(("State=%d", protocol->state));
904 switch(protocol->state) {
905 case SILC_PROTOCOL_STATE_START:
911 if (ctx->responder == TRUE) {
913 * We are receiving party
916 if (ctx->pfs == TRUE) {
918 * Use Perfect Forward Secrecy, ie. negotiate the key material
919 * using the SKE protocol.
922 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
923 /* Error in protocol */
924 protocol->state = SILC_PROTOCOL_STATE_ERROR;
925 silc_protocol_execute(protocol, client->schedule, 0, 300000);
928 ctx->ske = silc_ske_alloc();
929 ctx->ske->rng = client->rng;
930 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
931 silc_ske_get_group_by_number(conn->rekey->ske_group,
932 &ctx->ske->prop->group);
934 silc_ske_set_callbacks(ctx->ske,
935 silc_client_protocol_rekey_send_packet,
936 NULL, NULL, NULL, silc_ske_check_version,
939 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
940 if (status != SILC_SKE_STATUS_OK) {
941 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
944 protocol->state = SILC_PROTOCOL_STATE_ERROR;
945 silc_protocol_execute(protocol, client->schedule, 0, 300000);
949 /* Advance the protocol state */
951 silc_protocol_execute(protocol, client->schedule, 0, 0);
954 * Do normal and simple re-key.
957 /* Send the REKEY_DONE to indicate we will take new keys into use */
958 silc_client_packet_send(client, ctx->sock,
959 SILC_PACKET_REKEY_DONE,
960 NULL, 0, NULL, NULL, NULL, 0, FALSE);
962 /* After we send REKEY_DONE we must set the sending encryption
963 key to the new key since all packets after this packet must
964 encrypted with the new key. */
965 silc_client_protocol_rekey_generate(client, ctx, TRUE);
967 /* The protocol ends in next stage. */
968 protocol->state = SILC_PROTOCOL_STATE_END;
973 * We are the initiator of this protocol
976 /* Start the re-key by sending the REKEY packet */
977 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
978 NULL, 0, NULL, NULL, NULL, 0, FALSE);
980 if (ctx->pfs == TRUE) {
982 * Use Perfect Forward Secrecy, ie. negotiate the key material
983 * using the SKE protocol.
985 ctx->ske = silc_ske_alloc();
986 ctx->ske->rng = client->rng;
987 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
988 silc_ske_get_group_by_number(conn->rekey->ske_group,
989 &ctx->ske->prop->group);
991 silc_ske_set_callbacks(ctx->ske,
992 silc_client_protocol_rekey_send_packet,
993 NULL, NULL, NULL, silc_ske_check_version,
996 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL);
997 if (status != SILC_SKE_STATUS_OK) {
998 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1001 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1002 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1006 /* Advance the protocol state */
1010 * Do normal and simple re-key.
1013 /* Send the REKEY_DONE to indicate we will take new keys into use
1015 silc_client_packet_send(client, ctx->sock,
1016 SILC_PACKET_REKEY_DONE,
1017 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1019 /* After we send REKEY_DONE we must set the sending encryption
1020 key to the new key since all packets after this packet must
1021 encrypted with the new key. */
1022 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1024 /* The protocol ends in next stage. */
1025 protocol->state = SILC_PROTOCOL_STATE_END;
1033 * Second state, used only when oding re-key with PFS.
1035 if (ctx->responder == TRUE) {
1036 if (ctx->pfs == TRUE) {
1038 * Send our KE packe to the initiator now that we've processed
1039 * the initiator's KE packet.
1041 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1042 SILC_SKE_PK_TYPE_SILC);
1044 if (status != SILC_SKE_STATUS_OK) {
1045 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1048 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1049 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1055 if (ctx->pfs == TRUE) {
1057 * The packet type must be KE packet
1059 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1060 /* Error in protocol */
1061 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1062 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1065 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1066 if (status != SILC_SKE_STATUS_OK) {
1067 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1070 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1071 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1077 /* Send the REKEY_DONE to indicate we will take new keys into use
1079 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1080 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1082 /* After we send REKEY_DONE we must set the sending encryption
1083 key to the new key since all packets after this packet must
1084 encrypted with the new key. */
1085 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1087 /* The protocol ends in next stage. */
1088 protocol->state = SILC_PROTOCOL_STATE_END;
1091 case SILC_PROTOCOL_STATE_END:
1096 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1097 /* Error in protocol */
1098 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1099 silc_protocol_execute(protocol, client->schedule, 0, 0);
1102 /* We received the REKEY_DONE packet and all packets after this is
1103 encrypted with the new key so set the decryption key to the new key */
1104 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1106 /* Protocol has ended, call the final callback */
1107 if (protocol->final_callback)
1108 silc_protocol_execute_final(protocol, client->schedule);
1110 silc_protocol_free(protocol);
1113 case SILC_PROTOCOL_STATE_ERROR:
1118 if (ctx->pfs == TRUE) {
1119 /* Send abort notification */
1120 silc_ske_abort(ctx->ske, ctx->ske->status);
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_FAILURE:
1132 * We have received failure from remote
1135 /* On error the final callback is always called. */
1136 if (protocol->final_callback)
1137 silc_protocol_execute_final(protocol, client->schedule);
1139 silc_protocol_free(protocol);
1142 case SILC_PROTOCOL_STATE_UNKNOWN:
1148 /* Registers protocols used in client */
1150 void silc_client_protocols_register(void)
1152 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1153 silc_client_protocol_connection_auth);
1154 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1155 silc_client_protocol_key_exchange);
1156 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1157 silc_client_protocol_rekey);
1160 /* Unregisters protocols */
1162 void silc_client_protocols_unregister(void)
1164 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1165 silc_client_protocol_connection_auth);
1166 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1167 silc_client_protocol_key_exchange);
1168 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1169 silc_client_protocol_rekey);