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)
117 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
119 SILC_LOG_DEBUG(("Setting new keys into use"));
121 /* Allocate cipher to be used in the communication */
122 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
123 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
125 conn->send_key->cipher->set_key(conn->send_key->context,
126 keymat->send_enc_key,
127 keymat->enc_key_len);
128 conn->send_key->set_iv(conn->send_key, keymat->send_iv);
129 conn->receive_key->cipher->set_key(conn->receive_key->context,
130 keymat->receive_enc_key,
131 keymat->enc_key_len);
132 conn->receive_key->set_iv(conn->receive_key, keymat->receive_iv);
135 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
136 conn->rekey->send_enc_key =
137 silc_calloc(keymat->enc_key_len / 8,
138 sizeof(*conn->rekey->send_enc_key));
139 memcpy(conn->rekey->send_enc_key,
140 keymat->send_enc_key, keymat->enc_key_len / 8);
141 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
143 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
144 conn->rekey->pfs = TRUE;
145 conn->rekey->ske_group = silc_ske_group_get_number(group);
147 /* Save HMAC key to be used in the communication. */
148 silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac_send);
149 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, keymat->hmac_key_len);
150 conn->hmac_receive = conn->hmac_send;
152 /* Save the HASH function */
153 silc_hash_alloc(hash->hash->name, &conn->hash);
156 /* Checks the version string of the server. */
158 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
159 uint32 len, void *context)
161 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
162 SilcClient client = (SilcClient)ske->user_data;
163 SilcSKEStatus status = SILC_SKE_STATUS_OK;
165 int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
167 /* Check for initial version string */
168 if (!strstr(version, "SILC-1.0-"))
169 status = SILC_SKE_STATUS_BAD_VERSION;
171 /* Check software version */
175 status = SILC_SKE_STATUS_BAD_VERSION;
178 cp = strchr(cp, '.');
183 cp = strchr(cp, '.');
185 build = atoi(cp + 1);
187 cp = client->silc_client_version + 9;
189 status = SILC_SKE_STATUS_BAD_VERSION;
192 cp = strchr(cp, '.');
197 cp = strchr(cp, '.');
199 build2 = atoi(cp + 1);
202 status = SILC_SKE_STATUS_BAD_VERSION;
204 status = SILC_SKE_STATUS_BAD_VERSION;
206 if (status != SILC_SKE_STATUS_OK)
207 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
208 "We don't support server version `%s'", version);
213 /* Callback that is called by the SKE to indicate that it is safe to
214 continue the execution of the protocol. Is given as argument to the
215 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
216 This is called due to the fact that the public key verification
217 process is asynchronous and we must not continue the protocl until
218 the public key has been verified and this callback is called. */
220 static void silc_client_protocol_ke_continue(SilcSKE ske,
223 SilcProtocol protocol = (SilcProtocol)context;
224 SilcClientKEInternalContext *ctx =
225 (SilcClientKEInternalContext *)protocol->context;
226 SilcClient client = (SilcClient)ctx->client;
227 SilcClientConnection conn = ctx->sock->user_data;
229 SILC_LOG_DEBUG(("Start"));
231 if (ske->status != SILC_SKE_STATUS_OK) {
232 if (ske->status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
233 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
234 "Received unsupported server %s public key",
235 ctx->sock->hostname);
236 } else if (ske->status == SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED) {
237 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
238 "Remote host did not send its public key, even though "
241 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
242 "Error during key exchange protocol with server %s",
243 ctx->sock->hostname);
246 protocol->state = SILC_PROTOCOL_STATE_ERROR;
247 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
251 /* Send Ok to the other end. We will end the protocol as server
252 sends Ok to us when we will take the new keys into use. Do this
253 if we are initiator. This is happens when this callback was sent
254 to silc_ske_initiator_finish function. */
255 if (ctx->responder == FALSE) {
256 silc_ske_end(ctx->ske);
258 /* End the protocol on the next round */
259 protocol->state = SILC_PROTOCOL_STATE_END;
262 /* Advance protocol state and call the next state if we are responder.
263 This happens when this callback was sent to silc_ske_responder_phase_2
265 if (ctx->responder == TRUE) {
267 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
271 /* Performs key exchange protocol. This is used for both initiator
272 and responder key exchange. This may be called recursively. */
274 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
276 SilcProtocol protocol = (SilcProtocol)context;
277 SilcClientKEInternalContext *ctx =
278 (SilcClientKEInternalContext *)protocol->context;
279 SilcClient client = (SilcClient)ctx->client;
280 SilcClientConnection conn = ctx->sock->user_data;
281 SilcSKEStatus status = SILC_SKE_STATUS_OK;
283 SILC_LOG_DEBUG(("Start"));
285 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
286 protocol->state = SILC_PROTOCOL_STATE_START;
288 switch(protocol->state) {
289 case SILC_PROTOCOL_STATE_START:
296 /* Allocate Key Exchange object */
297 ske = silc_ske_alloc();
299 ske->rng = client->rng;
300 ske->user_data = (void *)client;
302 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
304 silc_client_protocol_ke_continue,
305 silc_ske_check_version,
308 if (ctx->responder == TRUE) {
309 /* Start the key exchange by processing the received security
310 properties packet from initiator. */
311 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
312 client->silc_client_version,
313 ctx->packet->buffer, TRUE);
315 SilcSKEStartPayload *start_payload;
317 /* Assemble security properties. */
318 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
319 client->silc_client_version,
322 /* Start the key exchange by sending our security properties
323 to the remote end. */
324 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
328 /* Return now if the procedure is pending */
329 if (status == SILC_SKE_STATUS_PENDING)
332 if (status != SILC_SKE_STATUS_OK) {
333 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
335 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
338 protocol->state = SILC_PROTOCOL_STATE_ERROR;
339 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
343 /* Advance protocol state and call the next state if we are responder */
345 if (ctx->responder == TRUE)
346 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
354 if (ctx->responder == TRUE) {
355 /* Sends the selected security properties to the initiator. */
357 silc_ske_responder_phase_1(ctx->ske,
358 ctx->ske->start_payload);
360 /* Call Phase-1 function. This processes the Key Exchange Start
361 paylaod reply we just got from the responder. The callback
362 function will receive the processed payload where we will
364 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
367 if (status != SILC_SKE_STATUS_OK) {
368 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
370 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
373 protocol->state = SILC_PROTOCOL_STATE_ERROR;
374 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
378 /* Advance protocol state and call next state if we are initiator */
380 if (ctx->responder == FALSE)
381 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
389 if (ctx->responder == TRUE) {
390 /* Process the received Key Exchange 1 Payload packet from
391 the initiator. This also creates our parts of the Diffie
392 Hellman algorithm. The silc_client_protocol_ke_continue will
393 be called after the public key has been verified. */
394 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
396 /* Call the Phase-2 function. This creates Diffie Hellman
397 key exchange parameters and sends our public part inside
398 Key Exhange 1 Payload to the responder. */
399 status = silc_ske_initiator_phase_2(ctx->ske,
401 client->private_key);
405 /* Return now if the procedure is pending */
406 if (status == SILC_SKE_STATUS_PENDING)
409 if (status != SILC_SKE_STATUS_OK) {
410 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
412 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
415 protocol->state = SILC_PROTOCOL_STATE_ERROR;
416 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
426 if (ctx->responder == TRUE) {
427 /* This creates the key exchange material and sends our
428 public parts to the initiator inside Key Exchange 2 Payload. */
430 silc_ske_responder_finish(ctx->ske,
431 client->public_key, client->private_key,
432 SILC_SKE_PK_TYPE_SILC);
434 /* End the protocol on the next round */
435 protocol->state = SILC_PROTOCOL_STATE_END;
437 /* Finish the protocol. This verifies the Key Exchange 2 payload
438 sent by responder. The silc_client_protocol_ke_continue will
439 be called after the public key has been verified. */
440 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
443 /* Return now if the procedure is pending */
444 if (status == SILC_SKE_STATUS_PENDING)
447 if (status != SILC_SKE_STATUS_OK) {
448 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
449 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
450 "Received unsupported server %s public key",
451 ctx->sock->hostname);
453 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
454 "Error during key exchange protocol with server %s",
455 ctx->sock->hostname);
457 protocol->state = SILC_PROTOCOL_STATE_ERROR;
458 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
464 case SILC_PROTOCOL_STATE_END:
469 SilcSKEKeyMaterial *keymat;
470 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
471 int hash_len = ctx->ske->prop->hash->hash->hash_len;
473 /* Process the key material */
474 keymat = silc_calloc(1, sizeof(*keymat));
475 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
477 if (status != SILC_SKE_STATUS_OK) {
478 protocol->state = SILC_PROTOCOL_STATE_ERROR;
479 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
480 silc_ske_free_key_material(keymat);
483 ctx->keymat = keymat;
485 /* Send Ok to the other end if we are responder. If we are initiator
486 we have sent this already. */
487 if (ctx->responder == TRUE)
488 silc_ske_end(ctx->ske);
490 /* Unregister the timeout task since the protocol has ended.
491 This was the timeout task to be executed if the protocol is
492 not completed fast enough. */
493 if (ctx->timeout_task)
494 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
496 /* Protocol has ended, call the final callback */
497 if (protocol->final_callback)
498 silc_protocol_execute_final(protocol, client->timeout_queue);
500 silc_protocol_free(protocol);
504 case SILC_PROTOCOL_STATE_ERROR:
506 * Error during protocol
509 /* Send abort notification */
510 silc_ske_abort(ctx->ske, ctx->ske->status);
512 /* On error the final callback is always called. */
513 if (protocol->final_callback)
514 silc_protocol_execute_final(protocol, client->timeout_queue);
516 silc_protocol_free(protocol);
519 case SILC_PROTOCOL_STATE_FAILURE:
521 * Received failure from remote.
524 /* Unregister the timeout task since the protocol has ended.
525 This was the timeout task to be executed if the protocol is
526 not completed fast enough. */
527 if (ctx->timeout_task)
528 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
530 /* On error the final callback is always called. */
531 if (protocol->final_callback)
532 silc_protocol_execute_final(protocol, client->timeout_queue);
534 silc_protocol_free(protocol);
536 case SILC_PROTOCOL_STATE_UNKNOWN:
542 * Connection Authentication protocol functions
546 silc_client_get_public_key_auth(SilcClient client,
548 unsigned char *auth_data,
549 uint32 *auth_data_len,
555 SilcPublicKey pub_key;
557 if (!silc_pkcs_load_public_key(filepath,&pub_key, SILC_PKCS_FILE_PEM))
558 if (!silc_pkcs_load_public_key(filepath, &pub_key, SILC_PKCS_FILE_BIN))
561 silc_pkcs_alloc(pub_key->name, &pkcs);
562 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
563 silc_pkcs_free(pkcs);
564 silc_pkcs_public_key_free(pub_key);
568 /* Make the authentication data. Protocol says it is HASH plus
570 len = ske->hash_len + ske->start_payload_copy->len;
571 auth = silc_buffer_alloc(len);
572 silc_buffer_pull_tail(auth, len);
573 silc_buffer_format(auth,
574 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
575 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
576 ske->start_payload_copy->len),
579 if (silc_pkcs_sign(pkcs, auth->data, auth->len, auth_data, auth_data_len)) {
580 silc_pkcs_free(pkcs);
581 silc_buffer_free(auth);
582 silc_pkcs_public_key_free(pub_key);
586 silc_pkcs_free(pkcs);
587 silc_buffer_free(auth);
588 silc_pkcs_public_key_free(pub_key);
592 /* Continues the connection authentication protocol. This funtion may
593 be called directly or used as SilcAskPassphrase callback. */
596 silc_client_conn_auth_continue(unsigned char *auth_data,
597 uint32 auth_data_len, void *context)
599 SilcProtocol protocol = (SilcProtocol)context;
600 SilcClientConnAuthInternalContext *ctx =
601 (SilcClientConnAuthInternalContext *)protocol->context;
602 SilcClient client = (SilcClient)ctx->client;
606 SILC_LOG_DEBUG(("Start"));
608 payload_len = 4 + auth_data_len;
609 packet = silc_buffer_alloc(payload_len);
610 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
611 silc_buffer_format(packet,
612 SILC_STR_UI_SHORT(payload_len),
613 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
614 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
617 /* Send the packet to server */
618 silc_client_packet_send(client, ctx->sock,
619 SILC_PACKET_CONNECTION_AUTH,
621 packet->data, packet->len, TRUE);
624 memset(auth_data, 0, auth_data_len);
625 silc_free(auth_data);
627 silc_buffer_free(packet);
629 /* Next state is end of protocol */
630 protocol->state = SILC_PROTOCOL_STATE_END;
633 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
635 SilcProtocol protocol = (SilcProtocol)context;
636 SilcClientConnAuthInternalContext *ctx =
637 (SilcClientConnAuthInternalContext *)protocol->context;
638 SilcClient client = (SilcClient)ctx->client;
639 SilcClientConnection conn = ctx->sock->user_data;
641 SILC_LOG_DEBUG(("Start"));
643 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
644 protocol->state = SILC_PROTOCOL_STATE_START;
646 switch(protocol->state) {
647 case SILC_PROTOCOL_STATE_START:
650 * Start protocol. We send authentication data to the server
651 * to be authenticated.
653 unsigned char *auth_data = NULL;
654 uint32 auth_data_len = 0;
656 switch(ctx->auth_meth) {
658 /* No authentication required */
661 case SILC_AUTH_PASSWORD:
662 /* Password authentication */
663 if (ctx->auth_data && ctx->auth_data_len) {
664 auth_data = ctx->auth_data;
665 auth_data_len = ctx->auth_data_len;
669 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO,
670 "Password authentication required by server %s",
671 ctx->sock->hostname);
672 client->ops->ask_passphrase(client, conn,
673 silc_client_conn_auth_continue,
678 case SILC_AUTH_PUBLIC_KEY:
680 unsigned char sign[1024];
682 /* Public key authentication */
683 silc_client_get_public_key_auth(client, ctx->auth_data,
684 sign, &auth_data_len,
686 auth_data = silc_calloc(auth_data_len, sizeof(*auth_data));
687 memcpy(auth_data, sign, auth_data_len);
692 silc_client_conn_auth_continue(auth_data,
693 auth_data_len, protocol);
697 case SILC_PROTOCOL_STATE_END:
700 * End protocol. Nothing special to be done here.
703 /* Protocol has ended, call the final callback */
704 if (protocol->final_callback)
705 silc_protocol_execute_final(protocol, client->timeout_queue);
707 silc_protocol_free(protocol);
711 case SILC_PROTOCOL_STATE_ERROR:
714 * Error. Send notify to remote.
716 unsigned char error[4];
718 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
720 /* Error in protocol. Send FAILURE packet. Although I don't think
721 this could ever happen on client side. */
722 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
723 NULL, 0, NULL, NULL, error, 4, TRUE);
725 /* On error the final callback is always called. */
726 if (protocol->final_callback)
727 silc_protocol_execute_final(protocol, client->timeout_queue);
729 silc_protocol_free(protocol);
732 case SILC_PROTOCOL_STATE_FAILURE:
734 * Received failure from remote.
737 /* On error the final callback is always called. */
738 if (protocol->final_callback)
739 silc_protocol_execute_final(protocol, client->timeout_queue);
741 silc_protocol_free(protocol);
744 case SILC_PROTOCOL_STATE_UNKNOWN:
750 * Re-key protocol routines
753 /* Actually takes the new keys into use. */
756 silc_client_protocol_rekey_validate(SilcClient client,
757 SilcClientRekeyInternalContext *ctx,
758 SilcSocketConnection sock,
759 SilcSKEKeyMaterial *keymat,
762 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
764 if (ctx->responder == TRUE) {
766 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
767 keymat->enc_key_len);
768 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
770 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
771 keymat->enc_key_len);
772 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
776 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
777 keymat->enc_key_len);
778 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
780 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
781 keymat->enc_key_len);
782 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
787 silc_hmac_alloc(conn->hmac_receive->hmac->name, NULL, &conn->hmac_send);
788 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key,
789 keymat->hmac_key_len);
791 silc_hmac_free(conn->hmac_receive);
792 conn->hmac_receive = conn->hmac_send;
795 /* Save the current sending encryption key */
797 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
798 silc_free(conn->rekey->send_enc_key);
799 conn->rekey->send_enc_key =
800 silc_calloc(keymat->enc_key_len / 8,
801 sizeof(*conn->rekey->send_enc_key));
802 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
803 keymat->enc_key_len / 8);
804 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
808 /* This function actually re-generates (when not using PFS) the keys and
809 takes them into use. */
812 silc_client_protocol_rekey_generate(SilcClient client,
813 SilcClientRekeyInternalContext *ctx,
816 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
817 SilcSKEKeyMaterial *keymat;
818 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
819 uint32 hash_len = conn->hash->hash->hash_len;
821 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
822 send ? "sending" : "receiving"));
824 /* Generate the new key */
825 keymat = silc_calloc(1, sizeof(*keymat));
826 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
827 conn->rekey->enc_key_len,
828 16, key_len, hash_len,
831 /* Set the keys into use */
832 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
834 silc_ske_free_key_material(keymat);
837 /* This function actually re-generates (with PFS) the keys and
838 takes them into use. */
841 silc_client_protocol_rekey_generate_pfs(SilcClient client,
842 SilcClientRekeyInternalContext *ctx,
845 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
846 SilcSKEKeyMaterial *keymat;
847 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
848 uint32 hash_len = conn->hash->hash->hash_len;
849 unsigned char *tmpbuf;
852 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
853 send ? "sending" : "receiving"));
855 /* Encode KEY to binary data */
856 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
858 /* Generate the new key */
859 keymat = silc_calloc(1, sizeof(*keymat));
860 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
863 /* Set the keys into use */
864 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
866 memset(tmpbuf, 0, klen);
868 silc_ske_free_key_material(keymat);
871 /* Packet sending callback. This function is provided as packet sending
872 routine to the Key Exchange functions. */
875 silc_client_protocol_rekey_send_packet(SilcSKE ske,
880 SilcProtocol protocol = (SilcProtocol)context;
881 SilcClientRekeyInternalContext *ctx =
882 (SilcClientRekeyInternalContext *)protocol->context;
883 SilcClient client = (SilcClient)ctx->client;
885 /* Send the packet immediately */
886 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
887 packet->data, packet->len, FALSE);
890 /* Performs re-key as defined in the SILC protocol specification. */
892 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
894 SilcProtocol protocol = (SilcProtocol)context;
895 SilcClientRekeyInternalContext *ctx =
896 (SilcClientRekeyInternalContext *)protocol->context;
897 SilcClient client = (SilcClient)ctx->client;
898 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
899 SilcSKEStatus status;
901 SILC_LOG_DEBUG(("Start"));
903 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
904 protocol->state = SILC_PROTOCOL_STATE_START;
906 SILC_LOG_DEBUG(("State=%d", protocol->state));
908 switch(protocol->state) {
909 case SILC_PROTOCOL_STATE_START:
915 if (ctx->responder == TRUE) {
917 * We are receiving party
920 if (ctx->pfs == TRUE) {
922 * Use Perfect Forward Secrecy, ie. negotiate the key material
923 * using the SKE protocol.
926 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
927 /* Error in protocol */
928 protocol->state = SILC_PROTOCOL_STATE_ERROR;
929 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
932 ctx->ske = silc_ske_alloc();
933 ctx->ske->rng = client->rng;
934 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
935 silc_ske_get_group_by_number(conn->rekey->ske_group,
936 &ctx->ske->prop->group);
938 silc_ske_set_callbacks(ctx->ske,
939 silc_client_protocol_rekey_send_packet,
940 NULL, NULL, NULL, silc_ske_check_version,
943 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
944 if (status != SILC_SKE_STATUS_OK) {
945 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
948 protocol->state = SILC_PROTOCOL_STATE_ERROR;
949 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
953 /* Advance the protocol state */
955 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
958 * Do normal and simple re-key.
961 /* Send the REKEY_DONE to indicate we will take new keys into use */
962 silc_client_packet_send(client, ctx->sock,
963 SILC_PACKET_REKEY_DONE,
964 NULL, 0, NULL, NULL, NULL, 0, FALSE);
966 /* After we send REKEY_DONE we must set the sending encryption
967 key to the new key since all packets after this packet must
968 encrypted with the new key. */
969 silc_client_protocol_rekey_generate(client, ctx, TRUE);
971 /* The protocol ends in next stage. */
972 protocol->state = SILC_PROTOCOL_STATE_END;
977 * We are the initiator of this protocol
980 /* Start the re-key by sending the REKEY packet */
981 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
982 NULL, 0, NULL, NULL, NULL, 0, FALSE);
984 if (ctx->pfs == TRUE) {
986 * Use Perfect Forward Secrecy, ie. negotiate the key material
987 * using the SKE protocol.
989 ctx->ske = silc_ske_alloc();
990 ctx->ske->rng = client->rng;
991 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
992 silc_ske_get_group_by_number(conn->rekey->ske_group,
993 &ctx->ske->prop->group);
995 silc_ske_set_callbacks(ctx->ske,
996 silc_client_protocol_rekey_send_packet,
997 NULL, NULL, NULL, silc_ske_check_version,
1000 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL);
1001 if (status != SILC_SKE_STATUS_OK) {
1002 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1005 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1006 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1010 /* Advance the protocol state */
1014 * Do normal and simple re-key.
1017 /* Send the REKEY_DONE to indicate we will take new keys into use
1019 silc_client_packet_send(client, ctx->sock,
1020 SILC_PACKET_REKEY_DONE,
1021 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1023 /* After we send REKEY_DONE we must set the sending encryption
1024 key to the new key since all packets after this packet must
1025 encrypted with the new key. */
1026 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1028 /* The protocol ends in next stage. */
1029 protocol->state = SILC_PROTOCOL_STATE_END;
1037 * Second state, used only when oding re-key with PFS.
1039 if (ctx->responder == TRUE) {
1040 if (ctx->pfs == TRUE) {
1042 * Send our KE packe to the initiator now that we've processed
1043 * the initiator's KE packet.
1045 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1046 SILC_SKE_PK_TYPE_SILC);
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->timeout_queue, 0, 300000);
1059 if (ctx->pfs == TRUE) {
1061 * The packet type must be KE packet
1063 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1064 /* Error in protocol */
1065 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1066 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1069 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1070 if (status != SILC_SKE_STATUS_OK) {
1071 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1074 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1075 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1081 /* Send the REKEY_DONE to indicate we will take new keys into use
1083 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1084 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1086 /* After we send REKEY_DONE we must set the sending encryption
1087 key to the new key since all packets after this packet must
1088 encrypted with the new key. */
1089 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1091 /* The protocol ends in next stage. */
1092 protocol->state = SILC_PROTOCOL_STATE_END;
1095 case SILC_PROTOCOL_STATE_END:
1100 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1101 /* Error in protocol */
1102 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1103 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
1106 /* We received the REKEY_DONE packet and all packets after this is
1107 encrypted with the new key so set the decryption key to the new key */
1108 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1110 /* Protocol has ended, call the final callback */
1111 if (protocol->final_callback)
1112 silc_protocol_execute_final(protocol, client->timeout_queue);
1114 silc_protocol_free(protocol);
1117 case SILC_PROTOCOL_STATE_ERROR:
1122 if (ctx->pfs == TRUE) {
1123 /* Send abort notification */
1124 silc_ske_abort(ctx->ske, ctx->ske->status);
1127 /* On error the final callback is always called. */
1128 if (protocol->final_callback)
1129 silc_protocol_execute_final(protocol, client->timeout_queue);
1131 silc_protocol_free(protocol);
1134 case SILC_PROTOCOL_STATE_FAILURE:
1136 * We have received failure from remote
1139 /* On error the final callback is always called. */
1140 if (protocol->final_callback)
1141 silc_protocol_execute_final(protocol, client->timeout_queue);
1143 silc_protocol_free(protocol);
1146 case SILC_PROTOCOL_STATE_UNKNOWN:
1152 /* Registers protocols used in client */
1154 void silc_client_protocols_register(void)
1156 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1157 silc_client_protocol_connection_auth);
1158 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1159 silc_client_protocol_key_exchange);
1160 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1161 silc_client_protocol_rekey);
1164 /* Unregisters protocols */
1166 void silc_client_protocols_unregister(void)
1168 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1169 silc_client_protocol_connection_auth);
1170 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1171 silc_client_protocol_key_exchange);
1172 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1173 silc_client_protocol_rekey);