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);
134 /* Allocate PKCS to be used */
136 /* XXX Do we ever need to allocate PKCS for the connection??
137 If yes, we need to change KE protocol to get the initiators
139 silc_pkcs_alloc(pkcs->pkcs->name, &conn->public_Key);
140 silc_pkcs_set_public_key(conn->public_key, ske->ke2_payload->pk_data,
141 ske->ke2_payload->pk_len);
144 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
145 conn->rekey->send_enc_key =
146 silc_calloc(keymat->enc_key_len / 8,
147 sizeof(*conn->rekey->send_enc_key));
148 memcpy(conn->rekey->send_enc_key,
149 keymat->send_enc_key, keymat->enc_key_len / 8);
150 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
152 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
153 conn->rekey->pfs = TRUE;
154 conn->rekey->ske_group = silc_ske_group_get_number(group);
156 /* Save HMAC key to be used in the communication. */
157 silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac_send);
158 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, keymat->hmac_key_len);
159 conn->hmac_receive = conn->hmac_send;
161 /* Save the HASH function */
162 silc_hash_alloc(hash->hash->name, &conn->hash);
165 /* Checks the version string of the server. */
167 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
168 uint32 len, void *context)
170 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
171 SilcClient client = (SilcClient)ske->user_data;
172 SilcSKEStatus status = SILC_SKE_STATUS_OK;
174 int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
176 /* Check for initial version string */
177 if (!strstr(version, "SILC-1.0-"))
178 status = SILC_SKE_STATUS_BAD_VERSION;
180 /* Check software version */
184 status = SILC_SKE_STATUS_BAD_VERSION;
187 cp = strchr(cp, '.');
192 cp = strchr(cp, '.');
194 build = atoi(cp + 1);
196 cp = client->silc_client_version + 9;
198 status = SILC_SKE_STATUS_BAD_VERSION;
201 cp = strchr(cp, '.');
206 cp = strchr(cp, '.');
208 build2 = atoi(cp + 1);
211 status = SILC_SKE_STATUS_BAD_VERSION;
213 status = SILC_SKE_STATUS_BAD_VERSION;
215 if (status != SILC_SKE_STATUS_OK)
216 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
217 "We don't support server version `%s'", version);
222 /* Callback that is called by the SKE to indicate that it is safe to
223 continue the execution of the protocol. Is given as argument to the
224 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
225 This is called due to the fact that the public key verification
226 process is asynchronous and we must not continue the protocl until
227 the public key has been verified and this callback is called. */
229 static void silc_client_protocol_ke_continue(SilcSKE ske,
232 SilcProtocol protocol = (SilcProtocol)context;
233 SilcClientKEInternalContext *ctx =
234 (SilcClientKEInternalContext *)protocol->context;
235 SilcClient client = (SilcClient)ctx->client;
236 SilcClientConnection conn = ctx->sock->user_data;
238 SILC_LOG_DEBUG(("Start"));
240 if (ske->status != SILC_SKE_STATUS_OK) {
241 if (ske->status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
242 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
243 "Received unsupported server %s public key",
244 ctx->sock->hostname);
245 } else if (ske->status == SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED) {
246 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
247 "Remote host did not send its public key, even though "
250 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
251 "Error during key exchange protocol with server %s",
252 ctx->sock->hostname);
255 protocol->state = SILC_PROTOCOL_STATE_ERROR;
256 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
260 /* Send Ok to the other end. We will end the protocol as server
261 sends Ok to us when we will take the new keys into use. Do this
262 if we are initiator. This is happens when this callback was sent
263 to silc_ske_initiator_finish function. */
264 if (ctx->responder == FALSE) {
265 silc_ske_end(ctx->ske);
267 /* End the protocol on the next round */
268 protocol->state = SILC_PROTOCOL_STATE_END;
271 /* Advance protocol state and call the next state if we are responder.
272 This happens when this callback was sent to silc_ske_responder_phase_2
274 if (ctx->responder == TRUE) {
276 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
280 /* Performs key exchange protocol. This is used for both initiator
281 and responder key exchange. This may be called recursively. */
283 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
285 SilcProtocol protocol = (SilcProtocol)context;
286 SilcClientKEInternalContext *ctx =
287 (SilcClientKEInternalContext *)protocol->context;
288 SilcClient client = (SilcClient)ctx->client;
289 SilcClientConnection conn = ctx->sock->user_data;
290 SilcSKEStatus status = SILC_SKE_STATUS_OK;
292 SILC_LOG_DEBUG(("Start"));
294 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
295 protocol->state = SILC_PROTOCOL_STATE_START;
297 switch(protocol->state) {
298 case SILC_PROTOCOL_STATE_START:
305 /* Allocate Key Exchange object */
306 ske = silc_ske_alloc();
308 ske->rng = client->rng;
309 ske->user_data = (void *)client;
311 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
313 silc_client_protocol_ke_continue,
314 silc_ske_check_version,
317 if (ctx->responder == TRUE) {
318 /* Start the key exchange by processing the received security
319 properties packet from initiator. */
320 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
321 client->silc_client_version,
322 ctx->packet->buffer, TRUE);
324 SilcSKEStartPayload *start_payload;
326 /* Assemble security properties. */
327 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
328 client->silc_client_version,
331 /* Start the key exchange by sending our security properties
332 to the remote end. */
333 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
337 /* Return now if the procedure is pending */
338 if (status == SILC_SKE_STATUS_PENDING)
341 if (status != SILC_SKE_STATUS_OK) {
342 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
344 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
347 protocol->state = SILC_PROTOCOL_STATE_ERROR;
348 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
352 /* Advance protocol state and call the next state if we are responder */
354 if (ctx->responder == TRUE)
355 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
363 if (ctx->responder == TRUE) {
364 /* Sends the selected security properties to the initiator. */
366 silc_ske_responder_phase_1(ctx->ske,
367 ctx->ske->start_payload);
369 /* Call Phase-1 function. This processes the Key Exchange Start
370 paylaod reply we just got from the responder. The callback
371 function will receive the processed payload where we will
373 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
376 if (status != SILC_SKE_STATUS_OK) {
377 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
379 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
382 protocol->state = SILC_PROTOCOL_STATE_ERROR;
383 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
387 /* Advance protocol state and call next state if we are initiator */
389 if (ctx->responder == FALSE)
390 silc_protocol_execute(protocol, client->timeout_queue, 0, 100000);
398 if (ctx->responder == TRUE) {
399 /* Process the received Key Exchange 1 Payload packet from
400 the initiator. This also creates our parts of the Diffie
401 Hellman algorithm. The silc_client_protocol_ke_continue will
402 be called after the public key has been verified. */
403 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
405 /* Call the Phase-2 function. This creates Diffie Hellman
406 key exchange parameters and sends our public part inside
407 Key Exhange 1 Payload to the responder. */
408 status = silc_ske_initiator_phase_2(ctx->ske,
410 client->private_key);
414 /* Return now if the procedure is pending */
415 if (status == SILC_SKE_STATUS_PENDING)
418 if (status != SILC_SKE_STATUS_OK) {
419 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
421 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
424 protocol->state = SILC_PROTOCOL_STATE_ERROR;
425 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
435 if (ctx->responder == TRUE) {
436 /* This creates the key exchange material and sends our
437 public parts to the initiator inside Key Exchange 2 Payload. */
439 silc_ske_responder_finish(ctx->ske,
440 client->public_key, client->private_key,
441 SILC_SKE_PK_TYPE_SILC);
443 /* End the protocol on the next round */
444 protocol->state = SILC_PROTOCOL_STATE_END;
446 /* Finish the protocol. This verifies the Key Exchange 2 payload
447 sent by responder. The silc_client_protocol_ke_continue will
448 be called after the public key has been verified. */
449 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
452 /* Return now if the procedure is pending */
453 if (status == SILC_SKE_STATUS_PENDING)
456 if (status != SILC_SKE_STATUS_OK) {
457 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
458 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
459 "Received unsupported server %s public key",
460 ctx->sock->hostname);
462 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
463 "Error during key exchange protocol with server %s",
464 ctx->sock->hostname);
466 protocol->state = SILC_PROTOCOL_STATE_ERROR;
467 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
473 case SILC_PROTOCOL_STATE_END:
478 SilcSKEKeyMaterial *keymat;
479 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
480 int hash_len = ctx->ske->prop->hash->hash->hash_len;
482 /* Process the key material */
483 keymat = silc_calloc(1, sizeof(*keymat));
484 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
486 if (status != SILC_SKE_STATUS_OK) {
487 protocol->state = SILC_PROTOCOL_STATE_ERROR;
488 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
489 silc_ske_free_key_material(keymat);
492 ctx->keymat = keymat;
494 /* Send Ok to the other end if we are responder. If we are initiator
495 we have sent this already. */
496 if (ctx->responder == TRUE)
497 silc_ske_end(ctx->ske);
499 /* Unregister the timeout task since the protocol has ended.
500 This was the timeout task to be executed if the protocol is
501 not completed fast enough. */
502 if (ctx->timeout_task)
503 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
505 /* Protocol has ended, call the final callback */
506 if (protocol->final_callback)
507 silc_protocol_execute_final(protocol, client->timeout_queue);
509 silc_protocol_free(protocol);
513 case SILC_PROTOCOL_STATE_ERROR:
515 * Error during protocol
518 /* Send abort notification */
519 silc_ske_abort(ctx->ske, ctx->ske->status);
521 /* On error the final callback is always called. */
522 if (protocol->final_callback)
523 silc_protocol_execute_final(protocol, client->timeout_queue);
525 silc_protocol_free(protocol);
528 case SILC_PROTOCOL_STATE_FAILURE:
530 * Received failure from remote.
533 /* Unregister the timeout task since the protocol has ended.
534 This was the timeout task to be executed if the protocol is
535 not completed fast enough. */
536 if (ctx->timeout_task)
537 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
539 /* On error the final callback is always called. */
540 if (protocol->final_callback)
541 silc_protocol_execute_final(protocol, client->timeout_queue);
543 silc_protocol_free(protocol);
545 case SILC_PROTOCOL_STATE_UNKNOWN:
551 * Connection Authentication protocol functions
555 silc_client_get_public_key_auth(SilcClient client,
557 unsigned char *auth_data,
558 uint32 *auth_data_len,
564 SilcPublicKey pub_key;
566 if (!silc_pkcs_load_public_key(filepath,&pub_key, SILC_PKCS_FILE_PEM))
567 if (!silc_pkcs_load_public_key(filepath, &pub_key, SILC_PKCS_FILE_BIN))
570 silc_pkcs_alloc(pub_key->name, &pkcs);
571 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
572 silc_pkcs_free(pkcs);
573 silc_pkcs_public_key_free(pub_key);
577 /* Make the authentication data. Protocol says it is HASH plus
579 len = ske->hash_len + ske->start_payload_copy->len;
580 auth = silc_buffer_alloc(len);
581 silc_buffer_pull_tail(auth, len);
582 silc_buffer_format(auth,
583 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
584 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
585 ske->start_payload_copy->len),
588 if (silc_pkcs_sign(pkcs, auth->data, auth->len, auth_data, auth_data_len)) {
589 silc_pkcs_free(pkcs);
590 silc_buffer_free(auth);
591 silc_pkcs_public_key_free(pub_key);
595 silc_pkcs_free(pkcs);
596 silc_buffer_free(auth);
597 silc_pkcs_public_key_free(pub_key);
601 /* Continues the connection authentication protocol. This funtion may
602 be called directly or used as SilcAskPassphrase callback. */
605 silc_client_conn_auth_continue(unsigned char *auth_data,
606 uint32 auth_data_len, void *context)
608 SilcProtocol protocol = (SilcProtocol)context;
609 SilcClientConnAuthInternalContext *ctx =
610 (SilcClientConnAuthInternalContext *)protocol->context;
611 SilcClient client = (SilcClient)ctx->client;
615 SILC_LOG_DEBUG(("Start"));
617 payload_len = 4 + auth_data_len;
618 packet = silc_buffer_alloc(payload_len);
619 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
620 silc_buffer_format(packet,
621 SILC_STR_UI_SHORT(payload_len),
622 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
623 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
626 /* Send the packet to server */
627 silc_client_packet_send(client, ctx->sock,
628 SILC_PACKET_CONNECTION_AUTH,
630 packet->data, packet->len, TRUE);
633 memset(auth_data, 0, auth_data_len);
634 silc_free(auth_data);
636 silc_buffer_free(packet);
638 /* Next state is end of protocol */
639 protocol->state = SILC_PROTOCOL_STATE_END;
642 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
644 SilcProtocol protocol = (SilcProtocol)context;
645 SilcClientConnAuthInternalContext *ctx =
646 (SilcClientConnAuthInternalContext *)protocol->context;
647 SilcClient client = (SilcClient)ctx->client;
648 SilcClientConnection conn = ctx->sock->user_data;
650 SILC_LOG_DEBUG(("Start"));
652 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
653 protocol->state = SILC_PROTOCOL_STATE_START;
655 switch(protocol->state) {
656 case SILC_PROTOCOL_STATE_START:
659 * Start protocol. We send authentication data to the server
660 * to be authenticated.
662 unsigned char *auth_data = NULL;
663 uint32 auth_data_len = 0;
665 switch(ctx->auth_meth) {
667 /* No authentication required */
670 case SILC_AUTH_PASSWORD:
671 /* Password authentication */
672 if (ctx->auth_data && ctx->auth_data_len) {
673 auth_data = ctx->auth_data;
674 auth_data_len = ctx->auth_data_len;
678 client->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO,
679 "Password authentication required by server %s",
680 ctx->sock->hostname);
681 client->ops->ask_passphrase(client, conn,
682 silc_client_conn_auth_continue,
687 case SILC_AUTH_PUBLIC_KEY:
689 unsigned char sign[1024];
691 /* Public key authentication */
692 silc_client_get_public_key_auth(client, ctx->auth_data,
693 sign, &auth_data_len,
695 auth_data = silc_calloc(auth_data_len, sizeof(*auth_data));
696 memcpy(auth_data, sign, auth_data_len);
701 silc_client_conn_auth_continue(auth_data,
702 auth_data_len, protocol);
706 case SILC_PROTOCOL_STATE_END:
709 * End protocol. Nothing special to be done here.
712 /* Protocol has ended, call the final callback */
713 if (protocol->final_callback)
714 silc_protocol_execute_final(protocol, client->timeout_queue);
716 silc_protocol_free(protocol);
720 case SILC_PROTOCOL_STATE_ERROR:
723 * Error. Send notify to remote.
725 unsigned char error[4];
727 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
729 /* Error in protocol. Send FAILURE packet. Although I don't think
730 this could ever happen on client side. */
731 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
732 NULL, 0, NULL, NULL, error, 4, TRUE);
734 /* On error the final callback is always called. */
735 if (protocol->final_callback)
736 silc_protocol_execute_final(protocol, client->timeout_queue);
738 silc_protocol_free(protocol);
741 case SILC_PROTOCOL_STATE_FAILURE:
743 * Received failure from remote.
746 /* On error the final callback is always called. */
747 if (protocol->final_callback)
748 silc_protocol_execute_final(protocol, client->timeout_queue);
750 silc_protocol_free(protocol);
753 case SILC_PROTOCOL_STATE_UNKNOWN:
759 * Re-key protocol routines
762 /* Actually takes the new keys into use. */
765 silc_client_protocol_rekey_validate(SilcClient client,
766 SilcClientRekeyInternalContext *ctx,
767 SilcSocketConnection sock,
768 SilcSKEKeyMaterial *keymat,
771 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
773 if (ctx->responder == TRUE) {
775 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
776 keymat->enc_key_len);
777 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
779 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
780 keymat->enc_key_len);
781 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
785 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
786 keymat->enc_key_len);
787 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
789 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
790 keymat->enc_key_len);
791 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
796 silc_hmac_alloc(conn->hmac_receive->hmac->name, NULL, &conn->hmac_send);
797 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key,
798 keymat->hmac_key_len);
800 silc_hmac_free(conn->hmac_receive);
801 conn->hmac_receive = conn->hmac_send;
804 /* Save the current sending encryption key */
806 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
807 silc_free(conn->rekey->send_enc_key);
808 conn->rekey->send_enc_key =
809 silc_calloc(keymat->enc_key_len / 8,
810 sizeof(*conn->rekey->send_enc_key));
811 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
812 keymat->enc_key_len / 8);
813 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
817 /* This function actually re-generates (when not using PFS) the keys and
818 takes them into use. */
821 silc_client_protocol_rekey_generate(SilcClient client,
822 SilcClientRekeyInternalContext *ctx,
825 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
826 SilcSKEKeyMaterial *keymat;
827 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
828 uint32 hash_len = conn->hash->hash->hash_len;
830 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
831 send ? "sending" : "receiving"));
833 /* Generate the new key */
834 keymat = silc_calloc(1, sizeof(*keymat));
835 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
836 conn->rekey->enc_key_len,
837 16, key_len, hash_len,
840 /* Set the keys into use */
841 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
843 silc_ske_free_key_material(keymat);
846 /* This function actually re-generates (with PFS) the keys and
847 takes them into use. */
850 silc_client_protocol_rekey_generate_pfs(SilcClient client,
851 SilcClientRekeyInternalContext *ctx,
854 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
855 SilcSKEKeyMaterial *keymat;
856 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
857 uint32 hash_len = conn->hash->hash->hash_len;
858 unsigned char *tmpbuf;
861 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
862 send ? "sending" : "receiving"));
864 /* Encode KEY to binary data */
865 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
867 /* Generate the new key */
868 keymat = silc_calloc(1, sizeof(*keymat));
869 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
872 /* Set the keys into use */
873 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
875 memset(tmpbuf, 0, klen);
877 silc_ske_free_key_material(keymat);
880 /* Packet sending callback. This function is provided as packet sending
881 routine to the Key Exchange functions. */
884 silc_client_protocol_rekey_send_packet(SilcSKE ske,
889 SilcProtocol protocol = (SilcProtocol)context;
890 SilcClientRekeyInternalContext *ctx =
891 (SilcClientRekeyInternalContext *)protocol->context;
892 SilcClient client = (SilcClient)ctx->client;
894 /* Send the packet immediately */
895 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
896 packet->data, packet->len, FALSE);
899 /* Performs re-key as defined in the SILC protocol specification. */
901 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
903 SilcProtocol protocol = (SilcProtocol)context;
904 SilcClientRekeyInternalContext *ctx =
905 (SilcClientRekeyInternalContext *)protocol->context;
906 SilcClient client = (SilcClient)ctx->client;
907 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
908 SilcSKEStatus status;
910 SILC_LOG_DEBUG(("Start"));
912 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
913 protocol->state = SILC_PROTOCOL_STATE_START;
915 SILC_LOG_DEBUG(("State=%d", protocol->state));
917 switch(protocol->state) {
918 case SILC_PROTOCOL_STATE_START:
924 if (ctx->responder == TRUE) {
926 * We are receiving party
929 if (ctx->pfs == TRUE) {
931 * Use Perfect Forward Secrecy, ie. negotiate the key material
932 * using the SKE protocol.
935 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
936 /* Error in protocol */
937 protocol->state = SILC_PROTOCOL_STATE_ERROR;
938 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
941 ctx->ske = silc_ske_alloc();
942 ctx->ske->rng = client->rng;
943 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
944 silc_ske_get_group_by_number(conn->rekey->ske_group,
945 &ctx->ske->prop->group);
947 silc_ske_set_callbacks(ctx->ske,
948 silc_client_protocol_rekey_send_packet,
949 NULL, NULL, NULL, silc_ske_check_version,
952 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
953 if (status != SILC_SKE_STATUS_OK) {
954 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
957 protocol->state = SILC_PROTOCOL_STATE_ERROR;
958 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
962 /* Advance the protocol state */
964 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
967 * Do normal and simple re-key.
970 /* Send the REKEY_DONE to indicate we will take new keys into use */
971 silc_client_packet_send(client, ctx->sock,
972 SILC_PACKET_REKEY_DONE,
973 NULL, 0, NULL, NULL, NULL, 0, FALSE);
975 /* After we send REKEY_DONE we must set the sending encryption
976 key to the new key since all packets after this packet must
977 encrypted with the new key. */
978 silc_client_protocol_rekey_generate(client, ctx, TRUE);
980 /* The protocol ends in next stage. */
981 protocol->state = SILC_PROTOCOL_STATE_END;
986 * We are the initiator of this protocol
989 /* Start the re-key by sending the REKEY packet */
990 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
991 NULL, 0, NULL, NULL, NULL, 0, FALSE);
993 if (ctx->pfs == TRUE) {
995 * Use Perfect Forward Secrecy, ie. negotiate the key material
996 * using the SKE protocol.
998 ctx->ske = silc_ske_alloc();
999 ctx->ske->rng = client->rng;
1000 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
1001 silc_ske_get_group_by_number(conn->rekey->ske_group,
1002 &ctx->ske->prop->group);
1004 silc_ske_set_callbacks(ctx->ske,
1005 silc_client_protocol_rekey_send_packet,
1006 NULL, NULL, NULL, silc_ske_check_version,
1009 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL);
1010 if (status != SILC_SKE_STATUS_OK) {
1011 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1014 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1015 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1019 /* Advance the protocol state */
1023 * Do normal and simple re-key.
1026 /* Send the REKEY_DONE to indicate we will take new keys into use
1028 silc_client_packet_send(client, ctx->sock,
1029 SILC_PACKET_REKEY_DONE,
1030 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1032 /* After we send REKEY_DONE we must set the sending encryption
1033 key to the new key since all packets after this packet must
1034 encrypted with the new key. */
1035 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1037 /* The protocol ends in next stage. */
1038 protocol->state = SILC_PROTOCOL_STATE_END;
1046 * Second state, used only when oding re-key with PFS.
1048 if (ctx->responder == TRUE) {
1049 if (ctx->pfs == TRUE) {
1051 * Send our KE packe to the initiator now that we've processed
1052 * the initiator's KE packet.
1054 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1055 SILC_SKE_PK_TYPE_SILC);
1057 if (status != SILC_SKE_STATUS_OK) {
1058 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1061 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1062 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1068 if (ctx->pfs == TRUE) {
1070 * The packet type must be KE packet
1072 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1073 /* Error in protocol */
1074 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1075 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1078 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1079 if (status != SILC_SKE_STATUS_OK) {
1080 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1083 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1084 silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1090 /* Send the REKEY_DONE to indicate we will take new keys into use
1092 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1093 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1095 /* After we send REKEY_DONE we must set the sending encryption
1096 key to the new key since all packets after this packet must
1097 encrypted with the new key. */
1098 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1100 /* The protocol ends in next stage. */
1101 protocol->state = SILC_PROTOCOL_STATE_END;
1104 case SILC_PROTOCOL_STATE_END:
1109 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1110 /* Error in protocol */
1111 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1112 silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
1115 /* We received the REKEY_DONE packet and all packets after this is
1116 encrypted with the new key so set the decryption key to the new key */
1117 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1119 /* Protocol has ended, call the final callback */
1120 if (protocol->final_callback)
1121 silc_protocol_execute_final(protocol, client->timeout_queue);
1123 silc_protocol_free(protocol);
1126 case SILC_PROTOCOL_STATE_ERROR:
1131 if (ctx->pfs == TRUE) {
1132 /* Send abort notification */
1133 silc_ske_abort(ctx->ske, ctx->ske->status);
1136 /* On error the final callback is always called. */
1137 if (protocol->final_callback)
1138 silc_protocol_execute_final(protocol, client->timeout_queue);
1140 silc_protocol_free(protocol);
1143 case SILC_PROTOCOL_STATE_FAILURE:
1145 * We have received failure from remote
1148 /* On error the final callback is always called. */
1149 if (protocol->final_callback)
1150 silc_protocol_execute_final(protocol, client->timeout_queue);
1152 silc_protocol_free(protocol);
1155 case SILC_PROTOCOL_STATE_UNKNOWN:
1161 /* Registers protocols used in client */
1163 void silc_client_protocols_register(void)
1165 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1166 silc_client_protocol_connection_auth);
1167 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1168 silc_client_protocol_key_exchange);
1169 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1170 silc_client_protocol_rekey);
1173 /* Unregisters protocols */
1175 void silc_client_protocols_unregister(void)
1177 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1178 silc_client_protocol_connection_auth);
1179 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1180 silc_client_protocol_key_exchange);
1181 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1182 silc_client_protocol_rekey);