5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Client side of the protocols.
25 #include "clientlibincludes.h"
26 #include "client_internal.h"
28 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
29 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
30 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
32 extern char *silc_version_string;
35 * Key Exhange protocol functions
38 /* Function that is called when SKE protocol sends packets to network. */
40 void silc_client_protocol_ke_send_packet(SilcSKE ske,
45 SilcProtocol protocol = (SilcProtocol)context;
46 SilcClientKEInternalContext *ctx =
47 (SilcClientKEInternalContext *)protocol->context;
48 SilcClient client = (SilcClient)ctx->client;
50 /* Send the packet immediately */
51 silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
52 packet->data, packet->len, TRUE);
55 /* Callback that is called when we have received KE2 payload from
56 responder. We try to verify the public key now. */
58 SilcSKEStatus silc_client_protocol_ke_verify_key(SilcSKE ske,
59 unsigned char *pk_data,
61 SilcSKEPKType pk_type,
64 SilcProtocol protocol = (SilcProtocol)context;
65 SilcClientKEInternalContext *ctx =
66 (SilcClientKEInternalContext *)protocol->context;
67 SilcClient client = (SilcClient)ctx->client;
69 SILC_LOG_DEBUG(("Start"));
71 /* Verify public key from user. */
72 if (!client->ops->verify_public_key(client, ctx->sock->user_data,
74 pk_data, pk_len, pk_type))
75 return SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
77 return SILC_SKE_STATUS_OK;
80 /* Sets the negotiated key material into use for particular connection. */
82 void silc_client_protocol_ke_set_keys(SilcSKE ske,
83 SilcSocketConnection sock,
84 SilcSKEKeyMaterial *keymat,
89 SilcSKEDiffieHellmanGroup group)
91 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
93 SILC_LOG_DEBUG(("Setting new keys into use"));
95 /* Allocate cipher to be used in the communication */
96 silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
97 silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
99 conn->send_key->cipher->set_key(conn->send_key->context,
100 keymat->send_enc_key,
101 keymat->enc_key_len);
102 conn->send_key->set_iv(conn->send_key, keymat->send_iv);
103 conn->receive_key->cipher->set_key(conn->receive_key->context,
104 keymat->receive_enc_key,
105 keymat->enc_key_len);
106 conn->receive_key->set_iv(conn->receive_key, keymat->receive_iv);
108 /* Allocate PKCS to be used */
110 /* XXX Do we ever need to allocate PKCS for the connection??
111 If yes, we need to change KE protocol to get the initiators
113 silc_pkcs_alloc(pkcs->pkcs->name, &conn->public_Key);
114 silc_pkcs_set_public_key(conn->public_key, ske->ke2_payload->pk_data,
115 ske->ke2_payload->pk_len);
118 conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
119 conn->rekey->send_enc_key =
120 silc_calloc(keymat->enc_key_len / 8,
121 sizeof(*conn->rekey->send_enc_key));
122 memcpy(conn->rekey->send_enc_key,
123 keymat->send_enc_key, keymat->enc_key_len / 8);
124 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
126 if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
127 conn->rekey->pfs = TRUE;
128 conn->rekey->ske_group = silc_ske_group_get_number(group);
130 /* Save HMAC key to be used in the communication. */
131 silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac_send);
132 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, keymat->hmac_key_len);
133 conn->hmac_receive = conn->hmac_send;
135 /* Save the HASH function */
136 silc_hash_alloc(hash->hash->name, &conn->hash);
139 /* Checks the version string of the server. */
141 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
144 SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
145 SilcClient client = (SilcClient)ske->user_data;
146 SilcSKEStatus status = SILC_SKE_STATUS_OK;
148 int maj = 0, min = 0, build = 0, maj2, min2, build2;
150 /* Check for initial version string */
151 if (!strstr(version, "SILC-1.0-"))
152 status = SILC_SKE_STATUS_BAD_VERSION;
154 /* Check software version */
158 cp = strchr(cp, '.');
163 cp = strchr(cp, '.');
165 build = atoi(cp + 1);
167 cp = silc_version_string + 9;
169 cp = strchr(cp, '.');
174 cp = strchr(cp, '.');
176 build2 = atoi(cp + 1);
179 status = SILC_SKE_STATUS_BAD_VERSION;
182 status = SILC_SKE_STATUS_BAD_VERSION;
185 if (status != SILC_SKE_STATUS_OK)
186 client->ops->say(client, conn,
187 "We don't support server version `%s'", version);
192 /* Performs key exchange protocol. This is used for both initiator
193 and responder key exchange. This may be called recursively. */
195 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
197 SilcProtocol protocol = (SilcProtocol)context;
198 SilcClientKEInternalContext *ctx =
199 (SilcClientKEInternalContext *)protocol->context;
200 SilcClient client = (SilcClient)ctx->client;
201 SilcClientConnection conn = ctx->sock->user_data;
202 SilcSKEStatus status = 0;
204 SILC_LOG_DEBUG(("Start"));
206 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
207 protocol->state = SILC_PROTOCOL_STATE_START;
209 switch(protocol->state) {
210 case SILC_PROTOCOL_STATE_START:
217 /* Allocate Key Exchange object */
218 ske = silc_ske_alloc();
220 ske->rng = client->rng;
221 ske->user_data = (void *)client;
223 if (ctx->responder == TRUE) {
224 /* Start the key exchange by processing the received security
225 properties packet from initiator. */
226 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
228 ctx->packet->buffer, TRUE,
231 SilcSKEStartPayload *start_payload;
233 /* Assemble security properties. */
234 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
238 /* Start the key exchange by sending our security properties
239 to the remote end. */
240 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
246 if (status != SILC_SKE_STATUS_OK) {
247 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
249 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
252 protocol->state = SILC_PROTOCOL_STATE_ERROR;
253 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
257 /* Advance protocol state and call the next state if we are responder */
259 if (ctx->responder == TRUE)
260 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
268 if (ctx->responder == TRUE) {
269 /* Sends the selected security properties to the initiator. */
271 silc_ske_responder_phase_1(ctx->ske,
272 ctx->ske->start_payload,
276 /* Call Phase-1 function. This processes the Key Exchange Start
277 paylaod reply we just got from the responder. The callback
278 function will receive the processed payload where we will
280 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer,
284 if (status != SILC_SKE_STATUS_OK) {
285 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
287 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
290 protocol->state = SILC_PROTOCOL_STATE_ERROR;
291 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
295 /* Advance protocol state and call next state if we are initiator */
297 if (ctx->responder == FALSE)
298 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
306 if (ctx->responder == TRUE) {
307 /* Process the received Key Exchange 1 Payload packet from
308 the initiator. This also creates our parts of the Diffie
309 Hellman algorithm. */
310 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
311 ctx->verify, context, NULL, NULL);
313 /* Call the Phase-2 function. This creates Diffie Hellman
314 key exchange parameters and sends our public part inside
315 Key Exhange 1 Payload to the responder. */
316 status = silc_ske_initiator_phase_2(ctx->ske,
323 if (status != SILC_SKE_STATUS_OK) {
324 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
326 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
329 protocol->state = SILC_PROTOCOL_STATE_ERROR;
330 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
334 /* Advance protocol state and call the next state if we are responder */
336 if (ctx->responder == TRUE)
337 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
345 if (ctx->responder == TRUE) {
346 /* This creates the key exchange material and sends our
347 public parts to the initiator inside Key Exchange 2 Payload. */
349 silc_ske_responder_finish(ctx->ske,
350 client->public_key, client->private_key,
351 SILC_SKE_PK_TYPE_SILC,
356 /* Finish the protocol. This verifies the Key Exchange 2 payload
357 sent by responder. */
358 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
359 ctx->verify, context, NULL, NULL);
362 if (status != SILC_SKE_STATUS_OK) {
364 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
365 client->ops->say(client, conn,
366 "Received unsupported server %s public key",
367 ctx->sock->hostname);
369 client->ops->say(client, conn,
370 "Error during key exchange protocol with server %s",
371 ctx->sock->hostname);
373 protocol->state = SILC_PROTOCOL_STATE_ERROR;
374 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
378 /* Send Ok to the other end. We will end the protocol as server
379 sends Ok to us when we will take the new keys into use. */
380 if (ctx->responder == FALSE)
381 silc_ske_end(ctx->ske, ctx->send_packet, context);
383 /* End the protocol on the next round */
384 protocol->state = SILC_PROTOCOL_STATE_END;
388 case SILC_PROTOCOL_STATE_END:
393 SilcSKEKeyMaterial *keymat;
394 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
395 int hash_len = ctx->ske->prop->hash->hash->hash_len;
397 /* Process the key material */
398 keymat = silc_calloc(1, sizeof(*keymat));
399 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
401 if (status != SILC_SKE_STATUS_OK) {
402 protocol->state = SILC_PROTOCOL_STATE_ERROR;
403 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 300000);
404 silc_ske_free_key_material(keymat);
407 ctx->keymat = keymat;
409 /* Send Ok to the other end if we are responder. If we are initiator
410 we have sent this already. */
411 if (ctx->responder == TRUE)
412 silc_ske_end(ctx->ske, ctx->send_packet, context);
414 /* Unregister the timeout task since the protocol has ended.
415 This was the timeout task to be executed if the protocol is
416 not completed fast enough. */
417 if (ctx->timeout_task)
418 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
420 /* Protocol has ended, call the final callback */
421 if (protocol->final_callback)
422 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
424 silc_protocol_free(protocol);
428 case SILC_PROTOCOL_STATE_ERROR:
430 * Error during protocol
433 /* Send abort notification */
434 silc_ske_abort(ctx->ske, ctx->ske->status,
435 ctx->send_packet, context);
437 /* On error the final callback is always called. */
438 if (protocol->final_callback)
439 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
441 silc_protocol_free(protocol);
444 case SILC_PROTOCOL_STATE_FAILURE:
446 * Received failure from remote.
449 /* Unregister the timeout task since the protocol has ended.
450 This was the timeout task to be executed if the protocol is
451 not completed fast enough. */
452 if (ctx->timeout_task)
453 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
455 /* On error the final callback is always called. */
456 if (protocol->final_callback)
457 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
459 silc_protocol_free(protocol);
461 case SILC_PROTOCOL_STATE_UNKNOWN:
467 * Connection Authentication protocol functions
471 silc_client_get_public_key_auth(SilcClient client,
473 unsigned char *auth_data,
474 uint32 *auth_data_len,
480 SilcPublicKey pub_key;
482 if (!silc_pkcs_load_public_key(filepath,&pub_key, SILC_PKCS_FILE_PEM))
483 if (!silc_pkcs_load_public_key(filepath, &pub_key, SILC_PKCS_FILE_BIN))
486 silc_pkcs_alloc(pub_key->name, &pkcs);
487 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
488 silc_pkcs_free(pkcs);
489 silc_pkcs_public_key_free(pub_key);
493 /* Make the authentication data. Protocol says it is HASH plus
495 len = ske->hash_len + ske->start_payload_copy->len;
496 auth = silc_buffer_alloc(len);
497 silc_buffer_pull_tail(auth, len);
498 silc_buffer_format(auth,
499 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
500 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
501 ske->start_payload_copy->len),
504 if (silc_pkcs_sign(pkcs, auth->data, auth->len, auth_data, auth_data_len)) {
505 silc_pkcs_free(pkcs);
506 silc_buffer_free(auth);
507 silc_pkcs_public_key_free(pub_key);
511 silc_pkcs_free(pkcs);
512 silc_buffer_free(auth);
513 silc_pkcs_public_key_free(pub_key);
517 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
519 SilcProtocol protocol = (SilcProtocol)context;
520 SilcClientConnAuthInternalContext *ctx =
521 (SilcClientConnAuthInternalContext *)protocol->context;
522 SilcClient client = (SilcClient)ctx->client;
523 SilcClientConnection conn = ctx->sock->user_data;
525 SILC_LOG_DEBUG(("Start"));
527 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
528 protocol->state = SILC_PROTOCOL_STATE_START;
530 switch(protocol->state) {
531 case SILC_PROTOCOL_STATE_START:
534 * Start protocol. We send authentication data to the server
535 * to be authenticated.
539 unsigned char *auth_data = NULL;
540 uint32 auth_data_len = 0;
542 switch(ctx->auth_meth) {
544 /* No authentication required */
547 case SILC_AUTH_PASSWORD:
548 /* Password authentication */
549 if (ctx->auth_data && ctx->auth_data_len) {
550 auth_data = ctx->auth_data;
551 auth_data_len = ctx->auth_data_len;
555 client->ops->say(client, conn,
556 "Password authentication required by server %s",
557 ctx->sock->hostname);
558 auth_data = client->ops->ask_passphrase(client, conn);
559 auth_data_len = strlen(auth_data);
562 case SILC_AUTH_PUBLIC_KEY:
564 unsigned char sign[1024];
566 /* Public key authentication */
567 silc_client_get_public_key_auth(client, ctx->auth_data,
568 sign, &auth_data_len,
570 auth_data = silc_calloc(auth_data_len, sizeof(*auth_data));
571 memcpy(auth_data, sign, auth_data_len);
576 payload_len = 4 + auth_data_len;
577 packet = silc_buffer_alloc(payload_len);
578 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
579 silc_buffer_format(packet,
580 SILC_STR_UI_SHORT(payload_len),
581 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
582 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
585 /* Send the packet to server */
586 silc_client_packet_send(client, ctx->sock,
587 SILC_PACKET_CONNECTION_AUTH,
589 packet->data, packet->len, TRUE);
592 memset(auth_data, 0, auth_data_len);
593 silc_free(auth_data);
595 silc_buffer_free(packet);
597 /* Next state is end of protocol */
598 protocol->state = SILC_PROTOCOL_STATE_END;
602 case SILC_PROTOCOL_STATE_END:
605 * End protocol. Nothing special to be done here.
608 /* Protocol has ended, call the final callback */
609 if (protocol->final_callback)
610 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
612 silc_protocol_free(protocol);
616 case SILC_PROTOCOL_STATE_ERROR:
619 * Error. Send notify to remote.
621 unsigned char error[4];
623 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
625 /* Error in protocol. Send FAILURE packet. Although I don't think
626 this could ever happen on client side. */
627 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
628 NULL, 0, NULL, NULL, error, 4, TRUE);
630 /* On error the final callback is always called. */
631 if (protocol->final_callback)
632 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
634 silc_protocol_free(protocol);
637 case SILC_PROTOCOL_STATE_FAILURE:
639 * Received failure from remote.
642 /* On error the final callback is always called. */
643 if (protocol->final_callback)
644 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
646 silc_protocol_free(protocol);
649 case SILC_PROTOCOL_STATE_UNKNOWN:
655 * Re-key protocol routines
658 /* Actually takes the new keys into use. */
661 silc_client_protocol_rekey_validate(SilcClient client,
662 SilcClientRekeyInternalContext *ctx,
663 SilcSocketConnection sock,
664 SilcSKEKeyMaterial *keymat,
667 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
669 if (ctx->responder == TRUE) {
671 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
672 keymat->enc_key_len);
673 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
675 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
676 keymat->enc_key_len);
677 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
681 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
682 keymat->enc_key_len);
683 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
685 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
686 keymat->enc_key_len);
687 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
692 silc_hmac_alloc(conn->hmac_receive->hmac->name, NULL, &conn->hmac_send);
693 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key,
694 keymat->hmac_key_len);
696 silc_hmac_free(conn->hmac_receive);
697 conn->hmac_receive = conn->hmac_send;
700 /* Save the current sending encryption key */
702 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
703 silc_free(conn->rekey->send_enc_key);
704 conn->rekey->send_enc_key =
705 silc_calloc(keymat->enc_key_len / 8,
706 sizeof(*conn->rekey->send_enc_key));
707 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
708 keymat->enc_key_len / 8);
709 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
713 /* This function actually re-generates (when not using PFS) the keys and
714 takes them into use. */
717 silc_client_protocol_rekey_generate(SilcClient client,
718 SilcClientRekeyInternalContext *ctx,
721 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
722 SilcSKEKeyMaterial *keymat;
723 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
724 uint32 hash_len = conn->hash->hash->hash_len;
726 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
727 send ? "sending" : "receiving"));
729 /* Generate the new key */
730 keymat = silc_calloc(1, sizeof(*keymat));
731 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
732 conn->rekey->enc_key_len,
733 16, key_len, hash_len,
736 /* Set the keys into use */
737 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
739 silc_ske_free_key_material(keymat);
742 /* This function actually re-generates (with PFS) the keys and
743 takes them into use. */
746 silc_client_protocol_rekey_generate_pfs(SilcClient client,
747 SilcClientRekeyInternalContext *ctx,
750 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
751 SilcSKEKeyMaterial *keymat;
752 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
753 uint32 hash_len = conn->hash->hash->hash_len;
754 unsigned char *tmpbuf;
757 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
758 send ? "sending" : "receiving"));
760 /* Encode KEY to binary data */
761 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
763 /* Generate the new key */
764 keymat = silc_calloc(1, sizeof(*keymat));
765 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
768 /* Set the keys into use */
769 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
771 memset(tmpbuf, 0, klen);
773 silc_ske_free_key_material(keymat);
776 /* Packet sending callback. This function is provided as packet sending
777 routine to the Key Exchange functions. */
780 silc_client_protocol_rekey_send_packet(SilcSKE ske,
785 SilcProtocol protocol = (SilcProtocol)context;
786 SilcClientRekeyInternalContext *ctx =
787 (SilcClientRekeyInternalContext *)protocol->context;
788 SilcClient client = (SilcClient)ctx->client;
790 /* Send the packet immediately */
791 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
792 packet->data, packet->len, FALSE);
795 /* Performs re-key as defined in the SILC protocol specification. */
797 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
799 SilcProtocol protocol = (SilcProtocol)context;
800 SilcClientRekeyInternalContext *ctx =
801 (SilcClientRekeyInternalContext *)protocol->context;
802 SilcClient client = (SilcClient)ctx->client;
803 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
804 SilcSKEStatus status;
806 SILC_LOG_DEBUG(("Start"));
808 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
809 protocol->state = SILC_PROTOCOL_STATE_START;
811 SILC_LOG_DEBUG(("State=%d", protocol->state));
813 switch(protocol->state) {
814 case SILC_PROTOCOL_STATE_START:
820 if (ctx->responder == TRUE) {
822 * We are receiving party
825 if (ctx->pfs == TRUE) {
827 * Use Perfect Forward Secrecy, ie. negotiate the key material
828 * using the SKE protocol.
831 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
832 /* Error in protocol */
833 protocol->state = SILC_PROTOCOL_STATE_ERROR;
834 protocol->execute(client->timeout_queue, 0, protocol, fd,
838 ctx->ske = silc_ske_alloc();
839 ctx->ske->rng = client->rng;
840 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
841 silc_ske_get_group_by_number(conn->rekey->ske_group,
842 &ctx->ske->prop->group);
844 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
845 NULL, NULL, NULL, NULL);
846 if (status != SILC_SKE_STATUS_OK) {
847 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
850 protocol->state = SILC_PROTOCOL_STATE_ERROR;
851 protocol->execute(client->timeout_queue, 0,
852 protocol, fd, 0, 300000);
856 /* Advance the protocol state */
858 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
861 * Do normal and simple re-key.
864 /* Send the REKEY_DONE to indicate we will take new keys into use */
865 silc_client_packet_send(client, ctx->sock,
866 SILC_PACKET_REKEY_DONE,
867 NULL, 0, NULL, NULL, NULL, 0, FALSE);
869 /* After we send REKEY_DONE we must set the sending encryption
870 key to the new key since all packets after this packet must
871 encrypted with the new key. */
872 silc_client_protocol_rekey_generate(client, ctx, TRUE);
874 /* The protocol ends in next stage. */
875 protocol->state = SILC_PROTOCOL_STATE_END;
880 * We are the initiator of this protocol
883 /* Start the re-key by sending the REKEY packet */
884 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
885 NULL, 0, NULL, NULL, NULL, 0, FALSE);
887 if (ctx->pfs == TRUE) {
889 * Use Perfect Forward Secrecy, ie. negotiate the key material
890 * using the SKE protocol.
892 ctx->ske = silc_ske_alloc();
893 ctx->ske->rng = client->rng;
894 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
895 silc_ske_get_group_by_number(conn->rekey->ske_group,
896 &ctx->ske->prop->group);
899 silc_ske_initiator_phase_2(ctx->ske, NULL, NULL,
900 silc_client_protocol_rekey_send_packet,
903 if (status != SILC_SKE_STATUS_OK) {
904 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
907 protocol->state = SILC_PROTOCOL_STATE_ERROR;
908 protocol->execute(client->timeout_queue, 0,
909 protocol, fd, 0, 300000);
913 /* Advance the protocol state */
917 * Do normal and simple re-key.
920 /* Send the REKEY_DONE to indicate we will take new keys into use
922 silc_client_packet_send(client, ctx->sock,
923 SILC_PACKET_REKEY_DONE,
924 NULL, 0, NULL, NULL, NULL, 0, FALSE);
926 /* After we send REKEY_DONE we must set the sending encryption
927 key to the new key since all packets after this packet must
928 encrypted with the new key. */
929 silc_client_protocol_rekey_generate(client, ctx, TRUE);
931 /* The protocol ends in next stage. */
932 protocol->state = SILC_PROTOCOL_STATE_END;
940 * Second state, used only when oding re-key with PFS.
942 if (ctx->responder == TRUE) {
943 if (ctx->pfs == TRUE) {
945 * Send our KE packe to the initiator now that we've processed
946 * the initiator's KE packet.
949 silc_ske_responder_finish(ctx->ske, NULL, NULL,
950 SILC_SKE_PK_TYPE_SILC,
951 silc_client_protocol_rekey_send_packet,
954 if (status != SILC_SKE_STATUS_OK) {
955 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
958 protocol->state = SILC_PROTOCOL_STATE_ERROR;
959 protocol->execute(client->timeout_queue, 0,
960 protocol, fd, 0, 300000);
966 if (ctx->pfs == TRUE) {
968 * The packet type must be KE packet
970 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
971 /* Error in protocol */
972 protocol->state = SILC_PROTOCOL_STATE_ERROR;
973 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 300000);
976 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
977 NULL, NULL, NULL, NULL);
978 if (status != SILC_SKE_STATUS_OK) {
979 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
982 protocol->state = SILC_PROTOCOL_STATE_ERROR;
983 protocol->execute(client->timeout_queue, 0,
984 protocol, fd, 0, 300000);
990 /* Send the REKEY_DONE to indicate we will take new keys into use
992 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
993 NULL, 0, NULL, NULL, NULL, 0, FALSE);
995 /* After we send REKEY_DONE we must set the sending encryption
996 key to the new key since all packets after this packet must
997 encrypted with the new key. */
998 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1000 /* The protocol ends in next stage. */
1001 protocol->state = SILC_PROTOCOL_STATE_END;
1004 case SILC_PROTOCOL_STATE_END:
1009 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1010 /* Error in protocol */
1011 protocol->state = SILC_PROTOCOL_STATE_ERROR;
1012 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
1015 /* We received the REKEY_DONE packet and all packets after this is
1016 encrypted with the new key so set the decryption key to the new key */
1017 silc_client_protocol_rekey_generate(client, ctx, FALSE);
1019 /* Protocol has ended, call the final callback */
1020 if (protocol->final_callback)
1021 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
1023 silc_protocol_free(protocol);
1026 case SILC_PROTOCOL_STATE_ERROR:
1031 if (ctx->pfs == TRUE) {
1032 /* Send abort notification */
1033 silc_ske_abort(ctx->ske, ctx->ske->status,
1034 silc_client_protocol_ke_send_packet,
1038 /* On error the final callback is always called. */
1039 if (protocol->final_callback)
1040 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
1042 silc_protocol_free(protocol);
1045 case SILC_PROTOCOL_STATE_FAILURE:
1047 * We have received failure from remote
1050 /* On error the final callback is always called. */
1051 if (protocol->final_callback)
1052 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
1054 silc_protocol_free(protocol);
1057 case SILC_PROTOCOL_STATE_UNKNOWN:
1063 /* Registers protocols used in client */
1065 void silc_client_protocols_register(void)
1067 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1068 silc_client_protocol_connection_auth);
1069 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1070 silc_client_protocol_key_exchange);
1071 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1072 silc_client_protocol_rekey);
1075 /* Unregisters protocols */
1077 void silc_client_protocols_unregister(void)
1079 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1080 silc_client_protocol_connection_auth);
1081 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1082 silc_client_protocol_key_exchange);
1083 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1084 silc_client_protocol_rekey);