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);
32 extern char *silc_version_string;
35 * Key Exhange protocol functions
38 /* Function that is called when SKE protocol sends packets to network. */
40 void silc_client_protocol_ke_send_packet(SilcSKE ske,
45 SilcProtocol protocol = (SilcProtocol)context;
46 SilcClientKEInternalContext *ctx =
47 (SilcClientKEInternalContext *)protocol->context;
48 SilcClient client = (SilcClient)ctx->client;
50 /* Send the packet immediately */
51 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
52 packet->data, packet->len, TRUE);
55 /* Public key verification callback. Called by the application. */
59 SilcSKEVerifyCbCompletion completion;
60 void *completion_context;
63 static void silc_client_verify_key_cb(bool success, void *context)
65 VerifyKeyContext verify = (VerifyKeyContext)context;
67 SILC_LOG_DEBUG(("Start"));
69 /* Call the completion callback back to the SKE */
70 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
71 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
72 verify->completion_context);
77 /* Callback that is called when we have received KE payload from
78 responder. We try to verify the public key now. */
80 void silc_client_protocol_ke_verify_key(SilcSKE ske,
81 unsigned char *pk_data,
83 SilcSKEPKType pk_type,
85 SilcSKEVerifyCbCompletion completion,
86 void *completion_context)
88 SilcProtocol protocol = (SilcProtocol)context;
89 SilcClientKEInternalContext *ctx =
90 (SilcClientKEInternalContext *)protocol->context;
91 SilcClient client = (SilcClient)ctx->client;
92 VerifyKeyContext verify;
94 SILC_LOG_DEBUG(("Start"));
96 verify = silc_calloc(1, sizeof(*verify));
98 verify->completion = completion;
99 verify->completion_context = completion_context;
101 /* Verify public key from user. */
102 client->ops->verify_public_key(client, ctx->sock->user_data,
104 pk_data, pk_len, pk_type,
105 silc_client_verify_key_cb, verify);
108 /* Sets the negotiated key material into use for particular connection. */
110 void silc_client_protocol_ke_set_keys(SilcSKE ske,
111 SilcSocketConnection sock,
112 SilcSKEKeyMaterial *keymat,
117 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);
127 conn->send_key->cipher->set_key(conn->send_key->context,
128 keymat->send_enc_key,
129 keymat->enc_key_len);
130 conn->send_key->set_iv(conn->send_key, keymat->send_iv);
131 conn->receive_key->cipher->set_key(conn->receive_key->context,
132 keymat->receive_enc_key,
133 keymat->enc_key_len);
134 conn->receive_key->set_iv(conn->receive_key, keymat->receive_iv);
136 /* Allocate PKCS to be used */
138 /* XXX Do we ever need to allocate PKCS for the connection??
139 If yes, we need to change KE protocol to get the initiators
141 silc_pkcs_alloc(pkcs->pkcs->name, &conn->public_Key);
142 silc_pkcs_set_public_key(conn->public_key, ske->ke2_payload->pk_data,
143 ske->ke2_payload->pk_len);
146 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
147 conn->rekey->send_enc_key =
148 silc_calloc(keymat->enc_key_len / 8,
149 sizeof(*conn->rekey->send_enc_key));
150 memcpy(conn->rekey->send_enc_key,
151 keymat->send_enc_key, keymat->enc_key_len / 8);
152 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
154 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
155 conn->rekey->pfs = TRUE;
156 conn->rekey->ske_group = silc_ske_group_get_number(group);
158 /* Save HMAC key to be used in the communication. */
159 silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac_send);
160 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, keymat->hmac_key_len);
161 conn->hmac_receive = conn->hmac_send;
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 uint32 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 = silc_version_string + 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 status = SILC_SKE_STATUS_BAD_VERSION;
217 if (status != SILC_SKE_STATUS_OK)
218 client->ops->say(client, conn,
219 "We don't support server version `%s'", version);
224 /* Callback that is called by the SKE to indicate that it is safe to
225 continue the execution of the protocol. Is given as argument to the
226 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
227 This is called due to the fact that the public key verification
228 process is asynchronous and we must not continue the protocl until
229 the public key has been verified and this callback is called. */
231 static void silc_client_protocol_ke_continue(SilcSKE ske,
234 SilcProtocol protocol = (SilcProtocol)context;
235 SilcClientKEInternalContext *ctx =
236 (SilcClientKEInternalContext *)protocol->context;
237 SilcClient client = (SilcClient)ctx->client;
238 SilcClientConnection conn = ctx->sock->user_data;
240 SILC_LOG_DEBUG(("Start"));
242 if (ske->status != SILC_SKE_STATUS_OK) {
243 if (ske->status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
244 client->ops->say(client, conn,
245 "Received unsupported server %s public key",
246 ctx->sock->hostname);
247 } else if (ske->status == SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED) {
248 client->ops->say(client, conn,
249 "Remote host did not send its public key, even though "
252 client->ops->say(client, conn,
253 "Error during key exchange protocol with server %s",
254 ctx->sock->hostname);
257 protocol->state = SILC_PROTOCOL_STATE_ERROR;
258 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
262 /* Send Ok to the other end. We will end the protocol as server
263 sends Ok to us when we will take the new keys into use. Do this
264 if we are initiator. This is happens when this callback was sent
265 to silc_ske_initiator_finish function. */
266 if (ctx->responder == FALSE) {
267 silc_ske_end(ctx->ske);
269 /* End the protocol on the next round */
270 protocol->state = SILC_PROTOCOL_STATE_END;
273 /* Advance protocol state and call the next state if we are responder.
274 This happens when this callback was sent to silc_ske_responder_phase_2
276 if (ctx->responder == TRUE) {
278 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
282 /* Performs key exchange protocol. This is used for both initiator
283 and responder key exchange. This may be called recursively. */
285 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
287 SilcProtocol protocol = (SilcProtocol)context;
288 SilcClientKEInternalContext *ctx =
289 (SilcClientKEInternalContext *)protocol->context;
290 SilcClient client = (SilcClient)ctx->client;
291 SilcClientConnection conn = ctx->sock->user_data;
292 SilcSKEStatus status = SILC_SKE_STATUS_OK;
294 SILC_LOG_DEBUG(("Start"));
296 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
297 protocol->state = SILC_PROTOCOL_STATE_START;
299 switch(protocol->state) {
300 case SILC_PROTOCOL_STATE_START:
307 /* Allocate Key Exchange object */
308 ske = silc_ske_alloc();
310 ske->rng = client->rng;
311 ske->user_data = (void *)client;
313 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
315 silc_client_protocol_ke_continue,
316 silc_ske_check_version,
319 if (ctx->responder == TRUE) {
320 /* Start the key exchange by processing the received security
321 properties packet from initiator. */
322 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
324 ctx->packet->buffer, TRUE);
326 SilcSKEStartPayload *start_payload;
328 /* Assemble security properties. */
329 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
333 /* Start the key exchange by sending our security properties
334 to the remote end. */
335 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
339 /* Return now if the procedure is pending */
340 if (status == SILC_SKE_STATUS_PENDING)
343 if (status != SILC_SKE_STATUS_OK) {
344 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
346 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
349 protocol->state = SILC_PROTOCOL_STATE_ERROR;
350 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
354 /* Advance protocol state and call the next state if we are responder */
356 if (ctx->responder == TRUE)
357 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
365 if (ctx->responder == TRUE) {
366 /* Sends the selected security properties to the initiator. */
368 silc_ske_responder_phase_1(ctx->ske,
369 ctx->ske->start_payload);
371 /* Call Phase-1 function. This processes the Key Exchange Start
372 paylaod reply we just got from the responder. The callback
373 function will receive the processed payload where we will
375 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
378 if (status != SILC_SKE_STATUS_OK) {
379 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
381 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
384 protocol->state = SILC_PROTOCOL_STATE_ERROR;
385 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
389 /* Advance protocol state and call next state if we are initiator */
391 if (ctx->responder == FALSE)
392 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
400 if (ctx->responder == TRUE) {
401 /* Process the received Key Exchange 1 Payload packet from
402 the initiator. This also creates our parts of the Diffie
403 Hellman algorithm. The silc_client_protocol_ke_continue will
404 be called after the public key has been verified. */
405 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
407 /* Call the Phase-2 function. This creates Diffie Hellman
408 key exchange parameters and sends our public part inside
409 Key Exhange 1 Payload to the responder. */
410 status = silc_ske_initiator_phase_2(ctx->ske,
412 client->private_key);
416 /* Return now if the procedure is pending */
417 if (status == SILC_SKE_STATUS_PENDING)
420 if (status != SILC_SKE_STATUS_OK) {
421 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
423 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
426 protocol->state = SILC_PROTOCOL_STATE_ERROR;
427 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
437 if (ctx->responder == TRUE) {
438 /* This creates the key exchange material and sends our
439 public parts to the initiator inside Key Exchange 2 Payload. */
441 silc_ske_responder_finish(ctx->ske,
442 client->public_key, client->private_key,
443 SILC_SKE_PK_TYPE_SILC);
445 /* End the protocol on the next round */
446 protocol->state = SILC_PROTOCOL_STATE_END;
448 /* Finish the protocol. This verifies the Key Exchange 2 payload
449 sent by responder. The silc_client_protocol_ke_continue will
450 be called after the public key has been verified. */
451 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
454 /* Return now if the procedure is pending */
455 if (status == SILC_SKE_STATUS_PENDING)
458 if (status != SILC_SKE_STATUS_OK) {
459 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
460 client->ops->say(client, conn,
461 "Received unsupported server %s public key",
462 ctx->sock->hostname);
464 client->ops->say(client, conn,
465 "Error during key exchange protocol with server %s",
466 ctx->sock->hostname);
468 protocol->state = SILC_PROTOCOL_STATE_ERROR;
469 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
475 case SILC_PROTOCOL_STATE_END:
480 SilcSKEKeyMaterial *keymat;
481 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
482 int hash_len = ctx->ske->prop->hash->hash->hash_len;
484 /* Process the key material */
485 keymat = silc_calloc(1, sizeof(*keymat));
486 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
488 if (status != SILC_SKE_STATUS_OK) {
489 protocol->state = SILC_PROTOCOL_STATE_ERROR;
490 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
491 silc_ske_free_key_material(keymat);
494 ctx->keymat = keymat;
496 /* Send Ok to the other end if we are responder. If we are initiator
497 we have sent this already. */
498 if (ctx->responder == TRUE)
499 silc_ske_end(ctx->ske);
501 /* Unregister the timeout task since the protocol has ended.
502 This was the timeout task to be executed if the protocol is
503 not completed fast enough. */
504 if (ctx->timeout_task)
505 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
507 /* Protocol has ended, call the final callback */
508 if (protocol->final_callback)
509 silc_protocol_execute_final(protocol, client->timeout_queue);
511 silc_protocol_free(protocol);
515 case SILC_PROTOCOL_STATE_ERROR:
517 * Error during protocol
520 /* Send abort notification */
521 silc_ske_abort(ctx->ske, ctx->ske->status);
523 /* On error the final callback is always called. */
524 if (protocol->final_callback)
525 silc_protocol_execute_final(protocol, client->timeout_queue);
527 silc_protocol_free(protocol);
530 case SILC_PROTOCOL_STATE_FAILURE:
532 * Received failure from remote.
535 /* Unregister the timeout task since the protocol has ended.
536 This was the timeout task to be executed if the protocol is
537 not completed fast enough. */
538 if (ctx->timeout_task)
539 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
541 /* On error the final callback is always called. */
542 if (protocol->final_callback)
543 silc_protocol_execute_final(protocol, client->timeout_queue);
545 silc_protocol_free(protocol);
547 case SILC_PROTOCOL_STATE_UNKNOWN:
553 * Connection Authentication protocol functions
557 silc_client_get_public_key_auth(SilcClient client,
559 unsigned char *auth_data,
560 uint32 *auth_data_len,
566 SilcPublicKey pub_key;
568 if (!silc_pkcs_load_public_key(filepath,&pub_key, SILC_PKCS_FILE_PEM))
569 if (!silc_pkcs_load_public_key(filepath, &pub_key, SILC_PKCS_FILE_BIN))
572 silc_pkcs_alloc(pub_key->name, &pkcs);
573 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
574 silc_pkcs_free(pkcs);
575 silc_pkcs_public_key_free(pub_key);
579 /* Make the authentication data. Protocol says it is HASH plus
581 len = ske->hash_len + ske->start_payload_copy->len;
582 auth = silc_buffer_alloc(len);
583 silc_buffer_pull_tail(auth, len);
584 silc_buffer_format(auth,
585 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
586 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
587 ske->start_payload_copy->len),
590 if (silc_pkcs_sign(pkcs, auth->data, auth->len, auth_data, auth_data_len)) {
591 silc_pkcs_free(pkcs);
592 silc_buffer_free(auth);
593 silc_pkcs_public_key_free(pub_key);
597 silc_pkcs_free(pkcs);
598 silc_buffer_free(auth);
599 silc_pkcs_public_key_free(pub_key);
603 /* Continues the connection authentication protocol. This funtion may
604 be called directly or used as SilcAskPassphrase callback. */
607 silc_client_conn_auth_continue(unsigned char *auth_data,
608 uint32 auth_data_len, void *context)
610 SilcProtocol protocol = (SilcProtocol)context;
611 SilcClientConnAuthInternalContext *ctx =
612 (SilcClientConnAuthInternalContext *)protocol->context;
613 SilcClient client = (SilcClient)ctx->client;
617 SILC_LOG_DEBUG(("Start"));
619 payload_len = 4 + auth_data_len;
620 packet = silc_buffer_alloc(payload_len);
621 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
622 silc_buffer_format(packet,
623 SILC_STR_UI_SHORT(payload_len),
624 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
625 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
628 /* Send the packet to server */
629 silc_client_packet_send(client, ctx->sock,
630 SILC_PACKET_CONNECTION_AUTH,
632 packet->data, packet->len, TRUE);
635 memset(auth_data, 0, auth_data_len);
636 silc_free(auth_data);
638 silc_buffer_free(packet);
640 /* Next state is end of protocol */
641 protocol->state = SILC_PROTOCOL_STATE_END;
644 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
646 SilcProtocol protocol = (SilcProtocol)context;
647 SilcClientConnAuthInternalContext *ctx =
648 (SilcClientConnAuthInternalContext *)protocol->context;
649 SilcClient client = (SilcClient)ctx->client;
650 SilcClientConnection conn = ctx->sock->user_data;
652 SILC_LOG_DEBUG(("Start"));
654 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
655 protocol->state = SILC_PROTOCOL_STATE_START;
657 switch(protocol->state) {
658 case SILC_PROTOCOL_STATE_START:
661 * Start protocol. We send authentication data to the server
662 * to be authenticated.
664 unsigned char *auth_data = NULL;
665 uint32 auth_data_len = 0;
667 switch(ctx->auth_meth) {
669 /* No authentication required */
672 case SILC_AUTH_PASSWORD:
673 /* Password authentication */
674 if (ctx->auth_data && ctx->auth_data_len) {
675 auth_data = ctx->auth_data;
676 auth_data_len = ctx->auth_data_len;
680 client->ops->say(client, conn,
681 "Password authentication required by server %s",
682 ctx->sock->hostname);
683 client->ops->ask_passphrase(client, conn,
684 silc_client_conn_auth_continue,
689 case SILC_AUTH_PUBLIC_KEY:
691 unsigned char sign[1024];
693 /* Public key authentication */
694 silc_client_get_public_key_auth(client, ctx->auth_data,
695 sign, &auth_data_len,
697 auth_data = silc_calloc(auth_data_len, sizeof(*auth_data));
698 memcpy(auth_data, sign, auth_data_len);
703 silc_client_conn_auth_continue(auth_data,
704 auth_data_len, protocol);
708 case SILC_PROTOCOL_STATE_END:
711 * End protocol. Nothing special to be done here.
714 /* Protocol has ended, call the final callback */
715 if (protocol->final_callback)
716 silc_protocol_execute_final(protocol, client->timeout_queue);
718 silc_protocol_free(protocol);
722 case SILC_PROTOCOL_STATE_ERROR:
725 * Error. Send notify to remote.
727 unsigned char error[4];
729 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
731 /* Error in protocol. Send FAILURE packet. Although I don't think
732 this could ever happen on client side. */
733 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
734 NULL, 0, NULL, NULL, error, 4, TRUE);
736 /* On error the final callback is always called. */
737 if (protocol->final_callback)
738 silc_protocol_execute_final(protocol, client->timeout_queue);
740 silc_protocol_free(protocol);
743 case SILC_PROTOCOL_STATE_FAILURE:
745 * Received failure from remote.
748 /* On error the final callback is always called. */
749 if (protocol->final_callback)
750 silc_protocol_execute_final(protocol, client->timeout_queue);
752 silc_protocol_free(protocol);
755 case SILC_PROTOCOL_STATE_UNKNOWN:
761 * Re-key protocol routines
764 /* Actually takes the new keys into use. */
767 silc_client_protocol_rekey_validate(SilcClient client,
768 SilcClientRekeyInternalContext *ctx,
769 SilcSocketConnection sock,
770 SilcSKEKeyMaterial *keymat,
773 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
775 if (ctx->responder == TRUE) {
777 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
778 keymat->enc_key_len);
779 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
781 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
782 keymat->enc_key_len);
783 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
787 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
788 keymat->enc_key_len);
789 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
791 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
792 keymat->enc_key_len);
793 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
798 silc_hmac_alloc(conn->hmac_receive->hmac->name, NULL, &conn->hmac_send);
799 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key,
800 keymat->hmac_key_len);
802 silc_hmac_free(conn->hmac_receive);
803 conn->hmac_receive = conn->hmac_send;
806 /* Save the current sending encryption key */
808 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
809 silc_free(conn->rekey->send_enc_key);
810 conn->rekey->send_enc_key =
811 silc_calloc(keymat->enc_key_len / 8,
812 sizeof(*conn->rekey->send_enc_key));
813 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
814 keymat->enc_key_len / 8);
815 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
819 /* This function actually re-generates (when not using PFS) the keys and
820 takes them into use. */
823 silc_client_protocol_rekey_generate(SilcClient client,
824 SilcClientRekeyInternalContext *ctx,
827 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
828 SilcSKEKeyMaterial *keymat;
829 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
830 uint32 hash_len = conn->hash->hash->hash_len;
832 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
833 send ? "sending" : "receiving"));
835 /* Generate the new key */
836 keymat = silc_calloc(1, sizeof(*keymat));
837 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
838 conn->rekey->enc_key_len,
839 16, key_len, hash_len,
842 /* Set the keys into use */
843 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
845 silc_ske_free_key_material(keymat);
848 /* This function actually re-generates (with PFS) the keys and
849 takes them into use. */
852 silc_client_protocol_rekey_generate_pfs(SilcClient client,
853 SilcClientRekeyInternalContext *ctx,
856 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
857 SilcSKEKeyMaterial *keymat;
858 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
859 uint32 hash_len = conn->hash->hash->hash_len;
860 unsigned char *tmpbuf;
863 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
864 send ? "sending" : "receiving"));
866 /* Encode KEY to binary data */
867 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
869 /* Generate the new key */
870 keymat = silc_calloc(1, sizeof(*keymat));
871 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
874 /* Set the keys into use */
875 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
877 memset(tmpbuf, 0, klen);
879 silc_ske_free_key_material(keymat);
882 /* Packet sending callback. This function is provided as packet sending
883 routine to the Key Exchange functions. */
886 silc_client_protocol_rekey_send_packet(SilcSKE ske,
891 SilcProtocol protocol = (SilcProtocol)context;
892 SilcClientRekeyInternalContext *ctx =
893 (SilcClientRekeyInternalContext *)protocol->context;
894 SilcClient client = (SilcClient)ctx->client;
896 /* Send the packet immediately */
897 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
898 packet->data, packet->len, FALSE);
901 /* Performs re-key as defined in the SILC protocol specification. */
903 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
905 SilcProtocol protocol = (SilcProtocol)context;
906 SilcClientRekeyInternalContext *ctx =
907 (SilcClientRekeyInternalContext *)protocol->context;
908 SilcClient client = (SilcClient)ctx->client;
909 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
910 SilcSKEStatus status;
912 SILC_LOG_DEBUG(("Start"));
914 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
915 protocol->state = SILC_PROTOCOL_STATE_START;
917 SILC_LOG_DEBUG(("State=%d", protocol->state));
919 switch(protocol->state) {
920 case SILC_PROTOCOL_STATE_START:
926 if (ctx->responder == TRUE) {
928 * We are receiving party
931 if (ctx->pfs == TRUE) {
933 * Use Perfect Forward Secrecy, ie. negotiate the key material
934 * using the SKE protocol.
937 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
938 /* Error in protocol */
939 protocol->state = SILC_PROTOCOL_STATE_ERROR;
940 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
943 ctx->ske = silc_ske_alloc();
944 ctx->ske->rng = client->rng;
945 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
946 silc_ske_get_group_by_number(conn->rekey->ske_group,
947 &ctx->ske->prop->group);
949 silc_ske_set_callbacks(ctx->ske,
950 silc_client_protocol_rekey_send_packet,
951 NULL, NULL, NULL, silc_ske_check_version,
954 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
955 if (status != SILC_SKE_STATUS_OK) {
956 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
959 protocol->state = SILC_PROTOCOL_STATE_ERROR;
960 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
964 /* Advance the protocol state */
966 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
969 * Do normal and simple re-key.
972 /* Send the REKEY_DONE to indicate we will take new keys into use */
973 silc_client_packet_send(client, ctx->sock,
974 SILC_PACKET_REKEY_DONE,
975 NULL, 0, NULL, NULL, NULL, 0, FALSE);
977 /* After we send REKEY_DONE we must set the sending encryption
978 key to the new key since all packets after this packet must
979 encrypted with the new key. */
980 silc_client_protocol_rekey_generate(client, ctx, TRUE);
982 /* The protocol ends in next stage. */
983 protocol->state = SILC_PROTOCOL_STATE_END;
988 * We are the initiator of this protocol
991 /* Start the re-key by sending the REKEY packet */
992 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
993 NULL, 0, NULL, NULL, NULL, 0, FALSE);
995 if (ctx->pfs == TRUE) {
997 * Use Perfect Forward Secrecy, ie. negotiate the key material
998 * using the SKE protocol.
1000 ctx->ske = silc_ske_alloc();
1001 ctx->ske->rng = client->rng;
1002 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
1003 silc_ske_get_group_by_number(conn->rekey->ske_group,
1004 &ctx->ske->prop->group);
1006 silc_ske_set_callbacks(ctx->ske,
1007 silc_client_protocol_rekey_send_packet,
1008 NULL, NULL, NULL, silc_ske_check_version,
1011 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL);
1012 if (status != SILC_SKE_STATUS_OK) {
1013 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1016 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1017 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1021 /* Advance the protocol state */
1025 * Do normal and simple re-key.
1028 /* Send the REKEY_DONE to indicate we will take new keys into use
1030 silc_client_packet_send(client, ctx->sock,
1031 SILC_PACKET_REKEY_DONE,
1032 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1034 /* After we send REKEY_DONE we must set the sending encryption
1035 key to the new key since all packets after this packet must
1036 encrypted with the new key. */
1037 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1039 /* The protocol ends in next stage. */
1040 protocol->state = SILC_PROTOCOL_STATE_END;
1048 * Second state, used only when oding re-key with PFS.
1050 if (ctx->responder == TRUE) {
1051 if (ctx->pfs == TRUE) {
1053 * Send our KE packe to the initiator now that we've processed
1054 * the initiator's KE packet.
1056 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1057 SILC_SKE_PK_TYPE_SILC);
1059 if (status != SILC_SKE_STATUS_OK) {
1060 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1063 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1064 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1070 if (ctx->pfs == TRUE) {
1072 * The packet type must be KE packet
1074 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1075 /* Error in protocol */
1076 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1077 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1080 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1081 if (status != SILC_SKE_STATUS_OK) {
1082 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1085 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1086 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1092 /* Send the REKEY_DONE to indicate we will take new keys into use
1094 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1095 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1097 /* After we send REKEY_DONE we must set the sending encryption
1098 key to the new key since all packets after this packet must
1099 encrypted with the new key. */
1100 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1102 /* The protocol ends in next stage. */
1103 protocol->state = SILC_PROTOCOL_STATE_END;
1106 case SILC_PROTOCOL_STATE_END:
1111 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1112 /* Error in protocol */
1113 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1114 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
1117 /* We received the REKEY_DONE packet and all packets after this is
1118 encrypted with the new key so set the decryption key to the new key */
1119 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1121 /* Protocol has ended, call the final callback */
1122 if (protocol->final_callback)
1123 silc_protocol_execute_final(protocol, client->timeout_queue);
1125 silc_protocol_free(protocol);
1128 case SILC_PROTOCOL_STATE_ERROR:
1133 if (ctx->pfs == TRUE) {
1134 /* Send abort notification */
1135 silc_ske_abort(ctx->ske, ctx->ske->status);
1138 /* On error the final callback is always called. */
1139 if (protocol->final_callback)
1140 silc_protocol_execute_final(protocol, client->timeout_queue);
1142 silc_protocol_free(protocol);
1145 case SILC_PROTOCOL_STATE_FAILURE:
1147 * We have received failure from remote
1150 /* On error the final callback is always called. */
1151 if (protocol->final_callback)
1152 silc_protocol_execute_final(protocol, client->timeout_queue);
1154 silc_protocol_free(protocol);
1157 case SILC_PROTOCOL_STATE_UNKNOWN:
1163 /* Registers protocols used in client */
1165 void silc_client_protocols_register(void)
1167 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1168 silc_client_protocol_connection_auth);
1169 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1170 silc_client_protocol_key_exchange);
1171 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1172 silc_client_protocol_rekey);
1175 /* Unregisters protocols */
1177 void silc_client_protocols_unregister(void)
1179 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1180 silc_client_protocol_connection_auth);
1181 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1182 silc_client_protocol_key_exchange);
1183 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1184 silc_client_protocol_rekey);