5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2004, 2006 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
22 #include "silcclient.h"
23 #include "client_internal.h"
25 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
26 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
27 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
30 * Key Exhange protocol functions
33 /* Function that is called when SKE protocol sends packets to network. */
35 void silc_client_protocol_ke_send_packet(SilcSKE ske,
40 SilcProtocol protocol = (SilcProtocol)context;
41 SilcClientKEInternalContext *ctx =
42 (SilcClientKEInternalContext *)protocol->context;
43 SilcClient client = (SilcClient)ctx->client;
45 /* Send the packet immediately */
46 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
47 packet->data, packet->len, TRUE);
50 /* Public key verification callback. Called by the application. */
54 SilcSKEVerifyCbCompletion completion;
55 void *completion_context;
58 static void silc_client_verify_key_cb(SilcBool success, void *context)
60 VerifyKeyContext verify = (VerifyKeyContext)context;
62 SILC_LOG_DEBUG(("Start"));
64 /* Call the completion callback back to the SKE */
65 verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
66 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
67 verify->completion_context);
72 /* Callback that is called when we have received KE payload from
73 responder. We try to verify the public key now. */
75 void silc_client_protocol_ke_verify_key(SilcSKE ske,
76 unsigned char *pk_data,
78 SilcSKEPKType pk_type,
80 SilcSKEVerifyCbCompletion completion,
81 void *completion_context)
83 SilcProtocol protocol = (SilcProtocol)context;
84 SilcClientKEInternalContext *ctx =
85 (SilcClientKEInternalContext *)protocol->context;
86 SilcClient client = (SilcClient)ctx->client;
87 VerifyKeyContext verify;
89 SILC_LOG_DEBUG(("Start"));
91 verify = silc_calloc(1, sizeof(*verify));
93 verify->completion = completion;
94 verify->completion_context = completion_context;
96 /* Verify public key from user. */
97 client->internal->ops->verify_public_key(client, ctx->sock->user_data,
99 pk_data, pk_len, pk_type,
100 silc_client_verify_key_cb, verify);
103 /* Sets the negotiated key material into use for particular connection. */
105 void silc_client_protocol_ke_set_keys(SilcSKE ske,
106 SilcSocketConnection sock,
107 SilcSKEKeyMaterial *keymat,
112 SilcSKEDiffieHellmanGroup group,
113 SilcBool is_responder)
115 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
116 const char *cname = silc_cipher_get_name(cipher);
118 SILC_LOG_DEBUG(("Setting new keys into use"));
120 /* Allocate cipher to be used in the communication */
121 silc_cipher_alloc((char *)cname, &conn->internal->send_key);
122 silc_cipher_alloc((char *)cname, &conn->internal->receive_key);
123 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
124 &conn->internal->hmac_send);
125 silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
126 &conn->internal->hmac_receive);
128 if (is_responder == TRUE) {
129 silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
130 keymat->enc_key_len);
131 silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv);
132 silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
133 keymat->enc_key_len);
134 silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv);
135 silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
136 keymat->hmac_key_len);
137 silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
138 keymat->hmac_key_len);
140 silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
141 keymat->enc_key_len);
142 silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv);
143 silc_cipher_set_key(conn->internal->receive_key, keymat->receive_enc_key,
144 keymat->enc_key_len);
145 silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv);
146 silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
147 keymat->hmac_key_len);
148 silc_hmac_set_key(conn->internal->hmac_receive, keymat->receive_hmac_key,
149 keymat->hmac_key_len);
153 conn->internal->rekey = silc_calloc(1, sizeof(*conn->internal->rekey));
154 conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
155 keymat->enc_key_len / 8);
156 conn->internal->rekey->enc_key_len = keymat->enc_key_len / 8;
158 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
159 conn->internal->rekey->pfs = TRUE;
160 conn->internal->rekey->ske_group = silc_ske_group_get_number(group);
162 /* Save the HASH function */
163 silc_hash_alloc(silc_hash_get_name(hash), &conn->internal->hash);
166 /* Checks the version string of the server. */
168 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
169 SilcUInt32 len, void *context)
171 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
172 SilcClient client = (SilcClient)ske->user_data;
173 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
175 if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
177 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
178 "We don't support server version `%s'",
180 return SILC_SKE_STATUS_BAD_VERSION;
183 if (!silc_parse_version_string(client->internal->silc_client_version,
184 &l_protocol_version, NULL, NULL,
186 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
187 "We don't support server version `%s'",
189 return SILC_SKE_STATUS_BAD_VERSION;
192 /* If remote is too new, don't connect */
193 if (l_protocol_version < r_protocol_version) {
194 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
195 "We don't support server version `%s'",
197 return SILC_SKE_STATUS_BAD_VERSION;
200 ske->sock->version = r_protocol_version;
202 return SILC_SKE_STATUS_OK;
205 /* Callback that is called by the SKE to indicate that it is safe to
206 continue the execution of the protocol. Is given as argument to the
207 silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
208 This is called due to the fact that the public key verification
209 process is asynchronous and we must not continue the protocl until
210 the public key has been verified and this callback is called. */
212 static void silc_client_protocol_ke_continue(SilcSKE ske,
215 SilcProtocol protocol = (SilcProtocol)context;
216 SilcClientKEInternalContext *ctx =
217 (SilcClientKEInternalContext *)protocol->context;
218 SilcClient client = (SilcClient)ctx->client;
219 SilcClientConnection conn = ctx->sock->user_data;
221 SILC_LOG_DEBUG(("Start"));
223 if (ske->status != SILC_SKE_STATUS_OK) {
224 /* Call failure client operation */
225 client->internal->ops->failure(client, conn, protocol,
226 (void *)ske->status);
227 protocol->state = SILC_PROTOCOL_STATE_ERROR;
228 silc_protocol_execute(protocol, client->schedule, 0, 0);
232 /* Send Ok to the other end. We will end the protocol as server
233 sends Ok to us when we will take the new keys into use. Do this
234 if we are initiator. This is happens when this callback was sent
235 to silc_ske_initiator_finish function. */
236 if (ctx->responder == FALSE) {
237 silc_ske_end(ctx->ske);
239 /* End the protocol on the next round */
240 protocol->state = SILC_PROTOCOL_STATE_END;
243 /* Advance protocol state and call the next state if we are responder.
244 This happens when this callback was sent to silc_ske_responder_phase_2
246 if (ctx->responder == TRUE) {
248 silc_protocol_execute(protocol, client->schedule, 0, 1);
252 /* Performs key exchange protocol. This is used for both initiator
253 and responder key exchange. This may be called recursively. */
255 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
257 SilcProtocol protocol = (SilcProtocol)context;
258 SilcClientKEInternalContext *ctx =
259 (SilcClientKEInternalContext *)protocol->context;
260 SilcClient client = (SilcClient)ctx->client;
261 SilcClientConnection conn = ctx->sock->user_data;
262 SilcSKEStatus status = SILC_SKE_STATUS_OK;
264 SILC_LOG_DEBUG(("Start"));
266 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
267 protocol->state = SILC_PROTOCOL_STATE_START;
269 switch(protocol->state) {
270 case SILC_PROTOCOL_STATE_START:
277 /* Allocate Key Exchange object */
278 ctx->ske = ske = silc_ske_alloc(client->rng, client);
280 silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
282 silc_client_protocol_ke_continue,
283 silc_ske_check_version,
286 if (ctx->responder == TRUE) {
288 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
290 protocol->state = SILC_PROTOCOL_STATE_ERROR;
291 silc_protocol_execute(protocol, client->schedule, 0, 0);
295 /* Start the key exchange by processing the received security
296 properties packet from initiator. */
298 silc_ske_responder_start(ske, ctx->rng, ctx->sock,
299 client->internal->silc_client_version,
300 ctx->packet->buffer, TRUE);
302 SilcSKEStartPayload *start_payload;
304 /* Assemble security properties. */
305 silc_ske_assemble_security_properties(
306 ske, SILC_SKE_SP_FLAG_MUTUAL,
307 client->internal->silc_client_version,
310 /* Start the key exchange by sending our security properties
311 to the remote end. */
312 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
316 /* Return now if the procedure is pending */
317 if (status == SILC_SKE_STATUS_PENDING)
320 if (status != SILC_SKE_STATUS_OK) {
321 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
323 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
326 protocol->state = SILC_PROTOCOL_STATE_ERROR;
327 silc_protocol_execute(protocol, client->schedule, 0, 0);
331 /* Advance protocol state and call the next state if we are responder */
333 if (ctx->responder == TRUE)
334 silc_protocol_execute(protocol, client->schedule, 0, 1);
342 if (ctx->responder == TRUE) {
343 /* Sends the selected security properties to the initiator. */
344 status = silc_ske_responder_phase_1(ctx->ske);
347 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
349 protocol->state = SILC_PROTOCOL_STATE_ERROR;
350 silc_protocol_execute(protocol, client->schedule, 0, 0);
354 /* Call Phase-1 function. This processes the Key Exchange Start
355 paylaod reply we just got from the responder. The callback
356 function will receive the processed payload where we will
358 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
361 if (status != SILC_SKE_STATUS_OK) {
362 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
364 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
367 protocol->state = SILC_PROTOCOL_STATE_ERROR;
368 silc_protocol_execute(protocol, client->schedule, 0, 0);
372 /* Advance protocol state and call next state if we are initiator */
374 if (ctx->responder == FALSE)
375 silc_protocol_execute(protocol, client->schedule, 0, 1);
383 if (ctx->responder == TRUE) {
385 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
387 protocol->state = SILC_PROTOCOL_STATE_ERROR;
388 silc_protocol_execute(protocol, client->schedule, 0, 0);
392 /* Process the received Key Exchange 1 Payload packet from
393 the initiator. This also creates our parts of the Diffie
394 Hellman algorithm. The silc_client_protocol_ke_continue will
395 be called after the public key has been verified. */
396 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
398 /* Call the Phase-2 function. This creates Diffie Hellman
399 key exchange parameters and sends our public part inside
400 Key Exhange 1 Payload to the responder. */
401 status = silc_ske_initiator_phase_2(ctx->ske,
404 SILC_SKE_PK_TYPE_SILC);
408 /* Return now if the procedure is pending */
409 if (status == SILC_SKE_STATUS_PENDING)
412 if (status != SILC_SKE_STATUS_OK) {
413 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
415 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
418 protocol->state = SILC_PROTOCOL_STATE_ERROR;
419 silc_protocol_execute(protocol, client->schedule, 0, 0);
429 if (ctx->responder == TRUE) {
430 /* This creates the key exchange material and sends our
431 public parts to the initiator inside Key Exchange 2 Payload. */
433 silc_ske_responder_finish(ctx->ske,
434 client->public_key, client->private_key,
435 SILC_SKE_PK_TYPE_SILC);
437 /* End the protocol on the next round */
438 protocol->state = SILC_PROTOCOL_STATE_END;
441 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
443 protocol->state = SILC_PROTOCOL_STATE_ERROR;
444 silc_protocol_execute(protocol, client->schedule, 0, 0);
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->internal->ops->say(
461 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
462 "Received unsupported server %s public key",
463 ctx->sock->hostname);
465 client->internal->ops->say(
466 client, conn, SILC_CLIENT_MESSAGE_AUDIT,
467 "Error during key exchange protocol with server %s",
468 ctx->sock->hostname);
470 protocol->state = SILC_PROTOCOL_STATE_ERROR;
471 silc_protocol_execute(protocol, client->schedule, 0, 0);
477 case SILC_PROTOCOL_STATE_END:
482 SilcSKEKeyMaterial *keymat;
483 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
484 int hash_len = silc_hash_len(ctx->ske->prop->hash);
486 /* Process the key material */
487 keymat = silc_calloc(1, sizeof(*keymat));
488 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
490 if (status != SILC_SKE_STATUS_OK) {
491 protocol->state = SILC_PROTOCOL_STATE_ERROR;
492 silc_protocol_execute(protocol, client->schedule, 0, 300000);
493 silc_ske_free_key_material(keymat);
496 ctx->keymat = keymat;
498 /* Send Ok to the other end if we are responder. If we are initiator
499 we have sent this already. */
500 if (ctx->responder == TRUE)
501 silc_ske_end(ctx->ske);
503 /* Unregister the timeout task since the protocol has ended.
504 This was the timeout task to be executed if the protocol is
505 not completed fast enough. */
506 if (ctx->timeout_task)
507 silc_schedule_task_del(client->schedule, ctx->timeout_task);
509 /* Protocol has ended, call the final callback */
510 if (protocol->final_callback)
511 silc_protocol_execute_final(protocol, client->schedule);
513 silc_protocol_free(protocol);
517 case SILC_PROTOCOL_STATE_ERROR:
519 * Error during protocol
522 /* Send abort notification */
523 silc_ske_abort(ctx->ske, ctx->ske->status);
525 /* On error the final callback is always called. */
526 if (protocol->final_callback)
527 silc_protocol_execute_final(protocol, client->schedule);
529 silc_protocol_free(protocol);
532 case SILC_PROTOCOL_STATE_FAILURE:
534 * Received failure from remote.
537 /* Unregister the timeout task since the protocol has ended.
538 This was the timeout task to be executed if the protocol is
539 not completed fast enough. */
540 if (ctx->timeout_task)
541 silc_schedule_task_del(client->schedule, ctx->timeout_task);
543 /* On error the final callback is always called. */
544 if (protocol->final_callback)
545 silc_protocol_execute_final(protocol, client->schedule);
547 silc_protocol_free(protocol);
549 case SILC_PROTOCOL_STATE_UNKNOWN:
555 * Connection Authentication protocol functions
559 silc_client_get_public_key_auth(SilcClient client,
560 SilcClientConnection conn,
561 unsigned char *auth_data,
562 SilcUInt32 *auth_data_len,
569 /* Use our default key */
572 /* Make the authentication data. Protocol says it is HASH plus
574 len = ske->hash_len + ske->start_payload_copy->len;
575 auth = silc_buffer_alloc(len);
576 silc_buffer_pull_tail(auth, len);
577 silc_buffer_format(auth,
578 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
579 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
580 ske->start_payload_copy->len),
583 if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
584 auth->len, auth_data, auth_data_len)) {
585 silc_buffer_free(auth);
589 silc_buffer_free(auth);
593 /* Continues the connection authentication protocol. This funtion may
594 be called directly or used as SilcAskPassphrase callback. */
597 silc_client_conn_auth_continue(unsigned char *auth_data,
598 SilcUInt32 auth_data_len, void *context)
600 SilcProtocol protocol = (SilcProtocol)context;
601 SilcClientConnAuthInternalContext *ctx =
602 (SilcClientConnAuthInternalContext *)protocol->context;
603 SilcClient client = (SilcClient)ctx->client;
606 unsigned char *autf8 = NULL;
608 SILC_LOG_DEBUG(("Sending authentication to server"));
610 /* Passphrase must be UTF-8 encoded, if it isn't encode it */
611 if (ctx->auth_meth == SILC_AUTH_PASSWORD &&
612 !silc_utf8_valid(auth_data, auth_data_len)) {
613 payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
615 autf8 = silc_calloc(payload_len, sizeof(*autf8));
616 auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
617 SILC_STRING_ASCII, autf8, payload_len);
621 payload_len = 4 + auth_data_len;
622 packet = silc_buffer_alloc(payload_len);
623 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
624 silc_buffer_format(packet,
625 SILC_STR_UI_SHORT(payload_len),
626 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
627 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
630 /* Send the packet to server */
631 silc_client_packet_send(client, ctx->sock,
632 SILC_PACKET_CONNECTION_AUTH,
634 packet->data, packet->len, TRUE);
635 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 SilcUInt32 auth_data_len = 0;
664 unsigned char sign[2048 + 1];
666 switch(ctx->auth_meth) {
668 /* No authentication required */
671 case SILC_AUTH_PASSWORD:
672 /* Password authentication */
673 if (ctx->auth_data && ctx->auth_data_len) {
674 auth_data = ctx->auth_data;
675 auth_data_len = ctx->auth_data_len;
679 client->internal->ops->say(
680 client, conn, SILC_CLIENT_MESSAGE_INFO,
681 "Password authentication required by server %s",
682 ctx->sock->hostname);
683 client->internal->ops->ask_passphrase(client, conn,
684 silc_client_conn_auth_continue,
689 case SILC_AUTH_PUBLIC_KEY:
690 if (!ctx->auth_data) {
691 /* Public key authentication */
692 silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
696 auth_data = ctx->auth_data;
697 auth_data_len = ctx->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->schedule);
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->schedule);
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->schedule);
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->internal->send_key, keymat->receive_enc_key,
778 keymat->enc_key_len);
779 silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv);
780 silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
781 keymat->hmac_key_len);
783 silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
784 keymat->enc_key_len);
785 silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv);
786 silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
787 keymat->hmac_key_len);
791 silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
792 keymat->enc_key_len);
793 silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv);
794 silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
795 keymat->hmac_key_len);
797 silc_cipher_set_key(conn->internal->receive_key,
798 keymat->receive_enc_key, keymat->enc_key_len);
799 silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv);
800 silc_hmac_set_key(conn->internal->hmac_receive,
801 keymat->receive_hmac_key, keymat->hmac_key_len);
805 /* Save the current sending encryption key */
807 memset(conn->internal->rekey->send_enc_key, 0,
808 conn->internal->rekey->enc_key_len);
809 silc_free(conn->internal->rekey->send_enc_key);
810 conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
811 keymat->enc_key_len / 8);
812 conn->internal->rekey->enc_key_len = keymat->enc_key_len / 8;
816 /* This function actually re-generates (when not using PFS) the keys and
817 takes them into use. */
820 silc_client_protocol_rekey_generate(SilcClient client,
821 SilcClientRekeyInternalContext *ctx,
824 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
825 SilcSKEKeyMaterial *keymat;
826 SilcUInt32 key_len = silc_cipher_get_key_len(conn->internal->send_key);
827 SilcUInt32 hash_len = silc_hash_len(conn->internal->hash);
829 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
830 send ? "sending" : "receiving"));
832 /* Generate the new key */
833 keymat = silc_calloc(1, sizeof(*keymat));
834 silc_ske_process_key_material_data(conn->internal->rekey->send_enc_key,
835 conn->internal->rekey->enc_key_len,
836 16, key_len, hash_len,
837 conn->internal->hash, keymat);
839 /* Set the keys into use */
840 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
842 silc_ske_free_key_material(keymat);
845 /* This function actually re-generates (with PFS) the keys and
846 takes them into use. */
849 silc_client_protocol_rekey_generate_pfs(SilcClient client,
850 SilcClientRekeyInternalContext *ctx,
853 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
854 SilcSKEKeyMaterial *keymat;
855 SilcUInt32 key_len = silc_cipher_get_key_len(conn->internal->send_key);
856 SilcUInt32 hash_len = silc_hash_len(conn->internal->hash);
857 unsigned char *tmpbuf;
860 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
861 send ? "sending" : "receiving"));
863 /* Encode KEY to binary data */
864 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
866 /* Generate the new key */
867 keymat = silc_calloc(1, sizeof(*keymat));
868 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
869 conn->internal->hash, keymat);
871 /* Set the keys into use */
872 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
874 memset(tmpbuf, 0, klen);
876 silc_ske_free_key_material(keymat);
879 /* Packet sending callback. This function is provided as packet sending
880 routine to the Key Exchange functions. */
883 silc_client_protocol_rekey_send_packet(SilcSKE ske,
888 SilcProtocol protocol = (SilcProtocol)context;
889 SilcClientRekeyInternalContext *ctx =
890 (SilcClientRekeyInternalContext *)protocol->context;
891 SilcClient client = (SilcClient)ctx->client;
893 /* Send the packet immediately */
894 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
895 packet->data, packet->len, FALSE);
898 /* Performs re-key as defined in the SILC protocol specification. */
900 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
902 SilcProtocol protocol = (SilcProtocol)context;
903 SilcClientRekeyInternalContext *ctx =
904 (SilcClientRekeyInternalContext *)protocol->context;
905 SilcClient client = (SilcClient)ctx->client;
906 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
907 SilcSKEStatus status;
909 SILC_LOG_DEBUG(("Start"));
911 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
912 protocol->state = SILC_PROTOCOL_STATE_START;
914 SILC_LOG_DEBUG(("State=%d", protocol->state));
916 switch(protocol->state) {
917 case SILC_PROTOCOL_STATE_START:
923 if (ctx->responder == TRUE) {
925 * We are receiving party
928 if (ctx->pfs == TRUE) {
930 * Use Perfect Forward Secrecy, ie. negotiate the key material
931 * using the SKE protocol.
935 SILC_LOG_WARNING(("Error during Re-key"));
936 protocol->state = SILC_PROTOCOL_STATE_ERROR;
937 silc_protocol_execute(protocol, client->schedule, 0, 300000);
941 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
942 /* Error in protocol */
943 protocol->state = SILC_PROTOCOL_STATE_ERROR;
944 silc_protocol_execute(protocol, client->schedule, 0, 300000);
947 ctx->ske = silc_ske_alloc(client->rng, client);
948 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
949 silc_ske_group_get_by_number(conn->internal->rekey->ske_group,
950 &ctx->ske->prop->group);
952 silc_ske_set_callbacks(ctx->ske,
953 silc_client_protocol_rekey_send_packet,
954 NULL, NULL, NULL, silc_ske_check_version,
957 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
958 if (status != SILC_SKE_STATUS_OK) {
959 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
962 protocol->state = SILC_PROTOCOL_STATE_ERROR;
963 silc_protocol_execute(protocol, client->schedule, 0, 300000);
967 /* Advance the protocol state */
969 silc_protocol_execute(protocol, client->schedule, 0, 0);
972 * Do normal and simple re-key.
975 /* Send the REKEY_DONE to indicate we will take new keys into use */
976 silc_client_packet_queue_purge(client, ctx->sock);
977 silc_client_packet_send(client, ctx->sock,
978 SILC_PACKET_REKEY_DONE,
979 NULL, 0, NULL, NULL, NULL, 0, FALSE);
981 /* After we send REKEY_DONE we must set the sending encryption
982 key to the new key since all packets after this packet must
983 encrypted with the new key. */
984 silc_client_protocol_rekey_generate(client, ctx, TRUE);
985 silc_client_packet_queue_purge(client, ctx->sock);
987 /* The protocol ends in next stage. */
988 protocol->state = SILC_PROTOCOL_STATE_END;
993 * We are the initiator of this protocol
996 /* Start the re-key by sending the REKEY packet */
997 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
998 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1000 if (ctx->pfs == TRUE) {
1002 * Use Perfect Forward Secrecy, ie. negotiate the key material
1003 * using the SKE protocol.
1005 ctx->ske = silc_ske_alloc(client->rng, client);
1006 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
1007 silc_ske_group_get_by_number(conn->internal->rekey->ske_group,
1008 &ctx->ske->prop->group);
1010 silc_ske_set_callbacks(ctx->ske,
1011 silc_client_protocol_rekey_send_packet,
1012 NULL, NULL, NULL, silc_ske_check_version,
1015 status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
1016 if (status != SILC_SKE_STATUS_OK) {
1017 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1020 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1021 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1025 /* Advance the protocol state */
1029 * Do normal and simple re-key.
1032 /* Send the REKEY_DONE to indicate we will take new keys into use
1034 silc_client_packet_queue_purge(client, ctx->sock);
1035 silc_client_packet_send(client, ctx->sock,
1036 SILC_PACKET_REKEY_DONE,
1037 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1039 /* After we send REKEY_DONE we must set the sending encryption
1040 key to the new key since all packets after this packet must
1041 encrypted with the new key. */
1042 silc_client_protocol_rekey_generate(client, ctx, TRUE);
1043 silc_client_packet_queue_purge(client, ctx->sock);
1045 /* The protocol ends in next stage. */
1046 protocol->state = SILC_PROTOCOL_STATE_END;
1054 * Second state, used only when oding re-key with PFS.
1056 if (ctx->responder == TRUE) {
1057 if (ctx->pfs == TRUE) {
1059 * Send our KE packe to the initiator now that we've processed
1060 * the initiator's KE packet.
1062 status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
1063 SILC_SKE_PK_TYPE_SILC);
1065 if (status != SILC_SKE_STATUS_OK) {
1066 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1069 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1070 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1076 if (ctx->pfs == TRUE) {
1078 * The packet type must be KE packet
1081 SILC_LOG_WARNING(("Error during Re-key"));
1082 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1083 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1087 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1088 /* Error in protocol */
1089 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1090 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1093 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1094 if (status != SILC_SKE_STATUS_OK) {
1095 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1098 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1099 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1105 /* Send the REKEY_DONE to indicate we will take new keys into use
1107 silc_client_packet_queue_purge(client, ctx->sock);
1108 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
1109 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1111 /* After we send REKEY_DONE we must set the sending encryption
1112 key to the new key since all packets after this packet must
1113 encrypted with the new key. */
1114 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1115 silc_client_packet_queue_purge(client, ctx->sock);
1117 /* The protocol ends in next stage. */
1118 protocol->state = SILC_PROTOCOL_STATE_END;
1121 case SILC_PROTOCOL_STATE_END:
1127 SILC_LOG_WARNING(("Error during Re-key"));
1128 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1129 silc_protocol_execute(protocol, client->schedule, 0, 300000);
1133 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1134 /* Error in protocol */
1135 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1136 silc_protocol_execute(protocol, client->schedule, 0, 0);
1139 /* We received the REKEY_DONE packet and all packets after this is
1140 encrypted with the new key so set the decryption key to the new key */
1141 if (ctx->pfs == TRUE)
1142 silc_client_protocol_rekey_generate_pfs(client, ctx, FALSE);
1144 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1145 silc_client_packet_queue_purge(client, ctx->sock);
1147 /* Protocol has ended, call the final callback */
1148 if (protocol->final_callback)
1149 silc_protocol_execute_final(protocol, client->schedule);
1151 silc_protocol_free(protocol);
1154 case SILC_PROTOCOL_STATE_ERROR:
1159 if (ctx->pfs == TRUE) {
1160 /* Send abort notification */
1161 silc_ske_abort(ctx->ske, ctx->ske->status);
1164 /* On error the final callback is always called. */
1165 if (protocol->final_callback)
1166 silc_protocol_execute_final(protocol, client->schedule);
1168 silc_protocol_free(protocol);
1171 case SILC_PROTOCOL_STATE_FAILURE:
1173 * We have received failure from remote
1176 /* On error the final callback is always called. */
1177 if (protocol->final_callback)
1178 silc_protocol_execute_final(protocol, client->schedule);
1180 silc_protocol_free(protocol);
1183 case SILC_PROTOCOL_STATE_UNKNOWN: