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 /* Check for initial version string */
149 if (!strstr(version, "SILC-1.0-"))
150 status = SILC_SKE_STATUS_BAD_VERSION;
152 /* Check software version */
154 if (len < strlen(silc_version_string))
155 status = SILC_SKE_STATUS_BAD_VERSION;
157 /* XXX for now there is no other tests due to the abnormal version
158 string that is used */
160 if (status != SILC_SKE_STATUS_OK)
161 client->ops->say(client, conn,
162 "We don't support server version `%s'", version);
167 /* Performs key exchange protocol. This is used for both initiator
168 and responder key exchange. This may be called recursively. */
170 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
172 SilcProtocol protocol = (SilcProtocol)context;
173 SilcClientKEInternalContext *ctx =
174 (SilcClientKEInternalContext *)protocol->context;
175 SilcClient client = (SilcClient)ctx->client;
176 SilcClientConnection conn = ctx->sock->user_data;
177 SilcSKEStatus status = 0;
179 SILC_LOG_DEBUG(("Start"));
181 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
182 protocol->state = SILC_PROTOCOL_STATE_START;
184 switch(protocol->state) {
185 case SILC_PROTOCOL_STATE_START:
192 /* Allocate Key Exchange object */
193 ske = silc_ske_alloc();
195 ske->rng = client->rng;
196 ske->user_data = (void *)client;
198 if (ctx->responder == TRUE) {
199 /* Start the key exchange by processing the received security
200 properties packet from initiator. */
201 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
203 ctx->packet->buffer, TRUE,
206 SilcSKEStartPayload *start_payload;
208 /* Assemble security properties. */
209 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
213 /* Start the key exchange by sending our security properties
214 to the remote end. */
215 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
221 if (status != SILC_SKE_STATUS_OK) {
222 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
224 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
227 protocol->state = SILC_PROTOCOL_STATE_ERROR;
228 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
232 /* Advance protocol state and call the next state if we are responder */
234 if (ctx->responder == TRUE)
235 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
243 if (ctx->responder == TRUE) {
244 /* Sends the selected security properties to the initiator. */
246 silc_ske_responder_phase_1(ctx->ske,
247 ctx->ske->start_payload,
251 /* Call Phase-1 function. This processes the Key Exchange Start
252 paylaod reply we just got from the responder. The callback
253 function will receive the processed payload where we will
255 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer,
259 if (status != SILC_SKE_STATUS_OK) {
260 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
262 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
265 protocol->state = SILC_PROTOCOL_STATE_ERROR;
266 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
270 /* Advance protocol state and call next state if we are initiator */
272 if (ctx->responder == FALSE)
273 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
281 if (ctx->responder == TRUE) {
282 /* Process the received Key Exchange 1 Payload packet from
283 the initiator. This also creates our parts of the Diffie
284 Hellman algorithm. */
285 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
286 ctx->verify, context, NULL, NULL);
288 /* Call the Phase-2 function. This creates Diffie Hellman
289 key exchange parameters and sends our public part inside
290 Key Exhange 1 Payload to the responder. */
291 status = silc_ske_initiator_phase_2(ctx->ske,
298 if (status != SILC_SKE_STATUS_OK) {
299 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
301 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
304 protocol->state = SILC_PROTOCOL_STATE_ERROR;
305 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
309 /* Advance protocol state and call the next state if we are responder */
311 if (ctx->responder == TRUE)
312 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
320 if (ctx->responder == TRUE) {
321 /* This creates the key exchange material and sends our
322 public parts to the initiator inside Key Exchange 2 Payload. */
324 silc_ske_responder_finish(ctx->ske,
325 client->public_key, client->private_key,
326 SILC_SKE_PK_TYPE_SILC,
331 /* Finish the protocol. This verifies the Key Exchange 2 payload
332 sent by responder. */
333 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
334 ctx->verify, context, NULL, NULL);
337 if (status != SILC_SKE_STATUS_OK) {
339 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
340 client->ops->say(client, conn,
341 "Received unsupported server %s public key",
342 ctx->sock->hostname);
344 client->ops->say(client, conn,
345 "Error during key exchange protocol with server %s",
346 ctx->sock->hostname);
348 protocol->state = SILC_PROTOCOL_STATE_ERROR;
349 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
353 /* Send Ok to the other end. We will end the protocol as server
354 sends Ok to us when we will take the new keys into use. */
355 if (ctx->responder == FALSE)
356 silc_ske_end(ctx->ske, ctx->send_packet, context);
358 /* End the protocol on the next round */
359 protocol->state = SILC_PROTOCOL_STATE_END;
363 case SILC_PROTOCOL_STATE_END:
368 SilcSKEKeyMaterial *keymat;
369 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
370 int hash_len = ctx->ske->prop->hash->hash->hash_len;
372 /* Process the key material */
373 keymat = silc_calloc(1, sizeof(*keymat));
374 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
376 if (status != SILC_SKE_STATUS_OK) {
377 protocol->state = SILC_PROTOCOL_STATE_ERROR;
378 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 300000);
379 silc_ske_free_key_material(keymat);
382 ctx->keymat = keymat;
384 /* Send Ok to the other end if we are responder. If we are initiator
385 we have sent this already. */
386 if (ctx->responder == TRUE)
387 silc_ske_end(ctx->ske, ctx->send_packet, context);
389 /* Unregister the timeout task since the protocol has ended.
390 This was the timeout task to be executed if the protocol is
391 not completed fast enough. */
392 if (ctx->timeout_task)
393 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
395 /* Protocol has ended, call the final callback */
396 if (protocol->final_callback)
397 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
399 silc_protocol_free(protocol);
403 case SILC_PROTOCOL_STATE_ERROR:
405 * Error during protocol
408 /* Send abort notification */
409 silc_ske_abort(ctx->ske, ctx->ske->status,
410 ctx->send_packet, context);
412 /* On error the final callback is always called. */
413 if (protocol->final_callback)
414 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
416 silc_protocol_free(protocol);
419 case SILC_PROTOCOL_STATE_FAILURE:
421 * Received failure from remote.
424 /* Unregister the timeout task since the protocol has ended.
425 This was the timeout task to be executed if the protocol is
426 not completed fast enough. */
427 if (ctx->timeout_task)
428 silc_task_unregister(client->timeout_queue, ctx->timeout_task);
430 /* On error the final callback is always called. */
431 if (protocol->final_callback)
432 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
434 silc_protocol_free(protocol);
436 case SILC_PROTOCOL_STATE_UNKNOWN:
442 * Connection Authentication protocol functions
446 silc_client_get_public_key_auth(SilcClient client,
448 unsigned char *auth_data,
449 uint32 *auth_data_len,
455 SilcPublicKey pub_key;
457 if (!silc_pkcs_load_public_key(filepath,&pub_key, SILC_PKCS_FILE_PEM))
458 if (!silc_pkcs_load_public_key(filepath, &pub_key, SILC_PKCS_FILE_BIN))
461 silc_pkcs_alloc(pub_key->name, &pkcs);
462 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
463 silc_pkcs_free(pkcs);
464 silc_pkcs_public_key_free(pub_key);
468 /* Make the authentication data. Protocol says it is HASH plus
470 len = ske->hash_len + ske->start_payload_copy->len;
471 auth = silc_buffer_alloc(len);
472 silc_buffer_pull_tail(auth, len);
473 silc_buffer_format(auth,
474 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
475 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
476 ske->start_payload_copy->len),
479 if (silc_pkcs_sign(pkcs, auth->data, auth->len, auth_data, auth_data_len)) {
480 silc_pkcs_free(pkcs);
481 silc_buffer_free(auth);
482 silc_pkcs_public_key_free(pub_key);
486 silc_pkcs_free(pkcs);
487 silc_buffer_free(auth);
488 silc_pkcs_public_key_free(pub_key);
492 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
494 SilcProtocol protocol = (SilcProtocol)context;
495 SilcClientConnAuthInternalContext *ctx =
496 (SilcClientConnAuthInternalContext *)protocol->context;
497 SilcClient client = (SilcClient)ctx->client;
498 SilcClientConnection conn = ctx->sock->user_data;
500 SILC_LOG_DEBUG(("Start"));
502 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
503 protocol->state = SILC_PROTOCOL_STATE_START;
505 switch(protocol->state) {
506 case SILC_PROTOCOL_STATE_START:
509 * Start protocol. We send authentication data to the server
510 * to be authenticated.
514 unsigned char *auth_data = NULL;
515 uint32 auth_data_len = 0;
517 switch(ctx->auth_meth) {
519 /* No authentication required */
522 case SILC_AUTH_PASSWORD:
523 /* Password authentication */
524 if (ctx->auth_data && ctx->auth_data_len) {
525 auth_data = ctx->auth_data;
526 auth_data_len = ctx->auth_data_len;
530 client->ops->say(client, conn,
531 "Password authentication required by server %s",
532 ctx->sock->hostname);
533 auth_data = client->ops->ask_passphrase(client, conn);
534 auth_data_len = strlen(auth_data);
537 case SILC_AUTH_PUBLIC_KEY:
539 unsigned char sign[1024];
541 /* Public key authentication */
542 silc_client_get_public_key_auth(client, ctx->auth_data,
543 sign, &auth_data_len,
545 auth_data = silc_calloc(auth_data_len, sizeof(*auth_data));
546 memcpy(auth_data, sign, auth_data_len);
551 payload_len = 4 + auth_data_len;
552 packet = silc_buffer_alloc(payload_len);
553 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
554 silc_buffer_format(packet,
555 SILC_STR_UI_SHORT(payload_len),
556 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
557 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
560 /* Send the packet to server */
561 silc_client_packet_send(client, ctx->sock,
562 SILC_PACKET_CONNECTION_AUTH,
564 packet->data, packet->len, TRUE);
567 memset(auth_data, 0, auth_data_len);
568 silc_free(auth_data);
570 silc_buffer_free(packet);
572 /* Next state is end of protocol */
573 protocol->state = SILC_PROTOCOL_STATE_END;
577 case SILC_PROTOCOL_STATE_END:
580 * End protocol. Nothing special to be done here.
583 /* Protocol has ended, call the final callback */
584 if (protocol->final_callback)
585 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
587 silc_protocol_free(protocol);
591 case SILC_PROTOCOL_STATE_ERROR:
594 * Error. Send notify to remote.
596 unsigned char error[4];
598 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
600 /* Error in protocol. Send FAILURE packet. Although I don't think
601 this could ever happen on client side. */
602 silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
603 NULL, 0, NULL, NULL, error, 4, TRUE);
605 /* On error the final callback is always called. */
606 if (protocol->final_callback)
607 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
609 silc_protocol_free(protocol);
612 case SILC_PROTOCOL_STATE_FAILURE:
614 * Received failure from remote.
617 /* On error the final callback is always called. */
618 if (protocol->final_callback)
619 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
621 silc_protocol_free(protocol);
624 case SILC_PROTOCOL_STATE_UNKNOWN:
630 * Re-key protocol routines
633 /* Actually takes the new keys into use. */
636 silc_client_protocol_rekey_validate(SilcClient client,
637 SilcClientRekeyInternalContext *ctx,
638 SilcSocketConnection sock,
639 SilcSKEKeyMaterial *keymat,
642 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
644 if (ctx->responder == TRUE) {
646 silc_cipher_set_key(conn->send_key, keymat->receive_enc_key,
647 keymat->enc_key_len);
648 silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
650 silc_cipher_set_key(conn->receive_key, keymat->send_enc_key,
651 keymat->enc_key_len);
652 silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
656 silc_cipher_set_key(conn->send_key, keymat->send_enc_key,
657 keymat->enc_key_len);
658 silc_cipher_set_iv(conn->send_key, keymat->send_iv);
660 silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key,
661 keymat->enc_key_len);
662 silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
667 silc_hmac_alloc(conn->hmac_receive->hmac->name, NULL, &conn->hmac_send);
668 silc_hmac_set_key(conn->hmac_send, keymat->hmac_key,
669 keymat->hmac_key_len);
671 silc_hmac_free(conn->hmac_receive);
672 conn->hmac_receive = conn->hmac_send;
675 /* Save the current sending encryption key */
677 memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
678 silc_free(conn->rekey->send_enc_key);
679 conn->rekey->send_enc_key =
680 silc_calloc(keymat->enc_key_len / 8,
681 sizeof(*conn->rekey->send_enc_key));
682 memcpy(conn->rekey->send_enc_key, keymat->send_enc_key,
683 keymat->enc_key_len / 8);
684 conn->rekey->enc_key_len = keymat->enc_key_len / 8;
688 /* This function actually re-generates (when not using PFS) the keys and
689 takes them into use. */
692 silc_client_protocol_rekey_generate(SilcClient client,
693 SilcClientRekeyInternalContext *ctx,
696 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
697 SilcSKEKeyMaterial *keymat;
698 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
699 uint32 hash_len = conn->hash->hash->hash_len;
701 SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
702 send ? "sending" : "receiving"));
704 /* Generate the new key */
705 keymat = silc_calloc(1, sizeof(*keymat));
706 silc_ske_process_key_material_data(conn->rekey->send_enc_key,
707 conn->rekey->enc_key_len,
708 16, key_len, hash_len,
711 /* Set the keys into use */
712 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
714 silc_ske_free_key_material(keymat);
717 /* This function actually re-generates (with PFS) the keys and
718 takes them into use. */
721 silc_client_protocol_rekey_generate_pfs(SilcClient client,
722 SilcClientRekeyInternalContext *ctx,
725 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
726 SilcSKEKeyMaterial *keymat;
727 uint32 key_len = silc_cipher_get_key_len(conn->send_key);
728 uint32 hash_len = conn->hash->hash->hash_len;
729 unsigned char *tmpbuf;
732 SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
733 send ? "sending" : "receiving"));
735 /* Encode KEY to binary data */
736 tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
738 /* Generate the new key */
739 keymat = silc_calloc(1, sizeof(*keymat));
740 silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
743 /* Set the keys into use */
744 silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
746 memset(tmpbuf, 0, klen);
748 silc_ske_free_key_material(keymat);
751 /* Packet sending callback. This function is provided as packet sending
752 routine to the Key Exchange functions. */
755 silc_client_protocol_rekey_send_packet(SilcSKE ske,
760 SilcProtocol protocol = (SilcProtocol)context;
761 SilcClientRekeyInternalContext *ctx =
762 (SilcClientRekeyInternalContext *)protocol->context;
763 SilcClient client = (SilcClient)ctx->client;
765 /* Send the packet immediately */
766 silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
767 packet->data, packet->len, FALSE);
770 /* Performs re-key as defined in the SILC protocol specification. */
772 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
774 SilcProtocol protocol = (SilcProtocol)context;
775 SilcClientRekeyInternalContext *ctx =
776 (SilcClientRekeyInternalContext *)protocol->context;
777 SilcClient client = (SilcClient)ctx->client;
778 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
779 SilcSKEStatus status;
781 SILC_LOG_DEBUG(("Start"));
783 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
784 protocol->state = SILC_PROTOCOL_STATE_START;
786 SILC_LOG_DEBUG(("State=%d", protocol->state));
788 switch(protocol->state) {
789 case SILC_PROTOCOL_STATE_START:
795 if (ctx->responder == TRUE) {
797 * We are receiving party
800 if (ctx->pfs == TRUE) {
802 * Use Perfect Forward Secrecy, ie. negotiate the key material
803 * using the SKE protocol.
806 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
807 /* Error in protocol */
808 protocol->state = SILC_PROTOCOL_STATE_ERROR;
809 protocol->execute(client->timeout_queue, 0, protocol, fd,
813 ctx->ske = silc_ske_alloc();
814 ctx->ske->rng = client->rng;
815 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
816 silc_ske_get_group_by_number(conn->rekey->ske_group,
817 &ctx->ske->prop->group);
819 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
820 NULL, NULL, NULL, NULL);
821 if (status != SILC_SKE_STATUS_OK) {
822 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
825 protocol->state = SILC_PROTOCOL_STATE_ERROR;
826 protocol->execute(client->timeout_queue, 0,
827 protocol, fd, 0, 300000);
831 /* Advance the protocol state */
833 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
836 * Do normal and simple re-key.
839 /* Send the REKEY_DONE to indicate we will take new keys into use */
840 silc_client_packet_send(client, ctx->sock,
841 SILC_PACKET_REKEY_DONE,
842 NULL, 0, NULL, NULL, NULL, 0, FALSE);
844 /* After we send REKEY_DONE we must set the sending encryption
845 key to the new key since all packets after this packet must
846 encrypted with the new key. */
847 silc_client_protocol_rekey_generate(client, ctx, TRUE);
849 /* The protocol ends in next stage. */
850 protocol->state = SILC_PROTOCOL_STATE_END;
855 * We are the initiator of this protocol
858 /* Start the re-key by sending the REKEY packet */
859 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
860 NULL, 0, NULL, NULL, NULL, 0, FALSE);
862 if (ctx->pfs == TRUE) {
864 * Use Perfect Forward Secrecy, ie. negotiate the key material
865 * using the SKE protocol.
867 ctx->ske = silc_ske_alloc();
868 ctx->ske->rng = client->rng;
869 ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
870 silc_ske_get_group_by_number(conn->rekey->ske_group,
871 &ctx->ske->prop->group);
874 silc_ske_initiator_phase_2(ctx->ske, NULL, NULL,
875 silc_client_protocol_rekey_send_packet,
878 if (status != SILC_SKE_STATUS_OK) {
879 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
882 protocol->state = SILC_PROTOCOL_STATE_ERROR;
883 protocol->execute(client->timeout_queue, 0,
884 protocol, fd, 0, 300000);
888 /* Advance the protocol state */
892 * Do normal and simple re-key.
895 /* Send the REKEY_DONE to indicate we will take new keys into use
897 silc_client_packet_send(client, ctx->sock,
898 SILC_PACKET_REKEY_DONE,
899 NULL, 0, NULL, NULL, NULL, 0, FALSE);
901 /* After we send REKEY_DONE we must set the sending encryption
902 key to the new key since all packets after this packet must
903 encrypted with the new key. */
904 silc_client_protocol_rekey_generate(client, ctx, TRUE);
906 /* The protocol ends in next stage. */
907 protocol->state = SILC_PROTOCOL_STATE_END;
915 * Second state, used only when oding re-key with PFS.
917 if (ctx->responder == TRUE) {
918 if (ctx->pfs == TRUE) {
920 * Send our KE packe to the initiator now that we've processed
921 * the initiator's KE packet.
924 silc_ske_responder_finish(ctx->ske, NULL, NULL,
925 SILC_SKE_PK_TYPE_SILC,
926 silc_client_protocol_rekey_send_packet,
929 if (status != SILC_SKE_STATUS_OK) {
930 SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
933 protocol->state = SILC_PROTOCOL_STATE_ERROR;
934 protocol->execute(client->timeout_queue, 0,
935 protocol, fd, 0, 300000);
941 if (ctx->pfs == TRUE) {
943 * The packet type must be KE packet
945 if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
946 /* Error in protocol */
947 protocol->state = SILC_PROTOCOL_STATE_ERROR;
948 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 300000);
951 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
952 NULL, NULL, NULL, NULL);
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 protocol->execute(client->timeout_queue, 0,
959 protocol, fd, 0, 300000);
965 /* Send the REKEY_DONE to indicate we will take new keys into use
967 silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
968 NULL, 0, NULL, NULL, NULL, 0, FALSE);
970 /* After we send REKEY_DONE we must set the sending encryption
971 key to the new key since all packets after this packet must
972 encrypted with the new key. */
973 silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
975 /* The protocol ends in next stage. */
976 protocol->state = SILC_PROTOCOL_STATE_END;
979 case SILC_PROTOCOL_STATE_END:
984 if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
985 /* Error in protocol */
986 protocol->state = SILC_PROTOCOL_STATE_ERROR;
987 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
990 /* We received the REKEY_DONE packet and all packets after this is
991 encrypted with the new key so set the decryption key to the new key */
992 silc_client_protocol_rekey_generate(client, ctx, FALSE);
994 /* Protocol has ended, call the final callback */
995 if (protocol->final_callback)
996 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
998 silc_protocol_free(protocol);
1001 case SILC_PROTOCOL_STATE_ERROR:
1006 if (ctx->pfs == TRUE) {
1007 /* Send abort notification */
1008 silc_ske_abort(ctx->ske, ctx->ske->status,
1009 silc_client_protocol_ke_send_packet,
1013 /* On error the final callback is always called. */
1014 if (protocol->final_callback)
1015 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
1017 silc_protocol_free(protocol);
1020 case SILC_PROTOCOL_STATE_FAILURE:
1022 * We have received failure from remote
1025 /* On error the final callback is always called. */
1026 if (protocol->final_callback)
1027 protocol->execute_final(client->timeout_queue, 0, protocol, fd);
1029 silc_protocol_free(protocol);
1032 case SILC_PROTOCOL_STATE_UNKNOWN:
1038 /* Registers protocols used in client */
1040 void silc_client_protocols_register(void)
1042 silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1043 silc_client_protocol_connection_auth);
1044 silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1045 silc_client_protocol_key_exchange);
1046 silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1047 silc_client_protocol_rekey);
1050 /* Unregisters protocols */
1052 void silc_client_protocols_unregister(void)
1054 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1055 silc_client_protocol_connection_auth);
1056 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1057 silc_client_protocol_key_exchange);
1058 silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1059 silc_client_protocol_rekey);