From 4559604b1e55af1f277b2420be645583450bb6e0 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Thu, 12 Apr 2001 22:00:21 +0000 Subject: [PATCH] updates. --- apps/silc/client_ops.c | 26 +++--- apps/silcd/server.c | 38 +++----- doc/draft-riikonen-silc-spec-01.nroff | 13 ++- lib/silcclient/README | 25 ++--- lib/silcclient/client.c | 2 + lib/silcclient/client.h | 3 +- lib/silcclient/client_channel.c | 2 +- lib/silcclient/client_prvmsg.c | 2 +- lib/silcclient/protocol.c | 129 +++++++++++++++++--------- lib/silcclient/protocol.h | 5 - lib/silccore/silcpacket.c | 2 - lib/silccore/silcpacket.h | 10 -- 12 files changed, 137 insertions(+), 120 deletions(-) diff --git a/apps/silc/client_ops.c b/apps/silc/client_ops.c index 3e01051c..985be666 100644 --- a/apps/silc/client_ops.c +++ b/apps/silc/client_ops.c @@ -1232,17 +1232,17 @@ int silc_key_agreement(SilcClient client, SilcClientConnection conn, /* SILC client operations */ SilcClientOperations ops = { - say: silc_say, - channel_message: silc_channel_message, - private_message: silc_private_message, - notify: silc_notify, - command: silc_command, - command_reply: silc_command_reply, - connect: silc_connect, - disconnect: silc_disconnect, - get_auth_method: silc_get_auth_method, - verify_public_key: silc_verify_public_key, - ask_passphrase: silc_ask_passphrase, - failure: silc_failure, - key_agreement: silc_key_agreement, + silc_say, + silc_channel_message, + silc_private_message, + silc_notify, + silc_command, + silc_command_reply, + silc_connect, + silc_disconnect, + silc_get_auth_method, + silc_verify_public_key, + silc_ask_passphrase, + silc_failure, + silc_key_agreement, }; diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 4ebe22b6..639c3bbb 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1526,37 +1526,21 @@ void silc_server_packet_parse(SilcPacketParserContext *parser_context) break; case SILC_SOCKET_TYPE_CLIENT: /* Parse the packet with timeout (unless protocol is active) */ - - /* If REKEY protocol is active we must proccess the packets synchronously - since we must assure that incoming packets that are encrypted with - the old key is processed before the new keys is set to use. */ - if (SILC_SERVER_IS_REKEY(sock)) - silc_server_packet_parse_real(server->timeout_queue, SILC_TASK_READ, - (void *)parser_context, sock->sock); - else - silc_task_register(server->timeout_queue, sock->sock, - silc_server_packet_parse_real, - (void *)parser_context, 0, - (sock->protocol ? 1 : 100000), - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + silc_task_register(server->timeout_queue, sock->sock, + silc_server_packet_parse_real, + (void *)parser_context, 0, + (sock->protocol ? 1 : 100000), + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); break; case SILC_SOCKET_TYPE_SERVER: case SILC_SOCKET_TYPE_ROUTER: /* Packets from servers are parsed as soon as possible */ - - /* If REKEY protocol is active we must proccess the packets synchronously - since we must assure that incoming packets that are encrypted with - the old key is processed before the new keys is set to use. */ - if (SILC_SERVER_IS_REKEY(sock)) - silc_server_packet_parse_real(server->timeout_queue, SILC_TASK_READ, - (void *)parser_context, sock->sock); - else - silc_task_register(server->timeout_queue, sock->sock, - silc_server_packet_parse_real, - (void *)parser_context, 0, 1, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + silc_task_register(server->timeout_queue, sock->sock, + silc_server_packet_parse_real, + (void *)parser_context, 0, 1, + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); break; default: return; diff --git a/doc/draft-riikonen-silc-spec-01.nroff b/doc/draft-riikonen-silc-spec-01.nroff index 854a0376..326c79cc 100644 --- a/doc/draft-riikonen-silc-spec-01.nroff +++ b/doc/draft-riikonen-silc-spec-01.nroff @@ -1791,10 +1791,15 @@ without executing SKE protocol. In this case, the new key is created by hashing the old key with hash function selected earlier in the SKE protocol. If the digest length of the hash function is too short for the key, then the key is distributed as described in section Processing the -Key Material in [SILC3]. After both parties has regenerated the session -key, both send SILC_PACKET_REKEY_DONE packet to each other. These packets -are still secured with the old key. After these packets, the following -packets must be protected with the new key. +Key Material in [SILC3]. + +After both parties has regenerated the session key, both send +SILC_PACKET_REKEY_DONE packet to each other. These packets are still +secured with the old key. After these packets, the following packets +must be protected with the new key. After sending the REKEY_DONE packet +all subsequent sent packets must be encrypted with the new key. After +receiving the REKEY_DONE packet all subsequent packets must be +decrypted with the new key. .ti 0 diff --git a/lib/silcclient/README b/lib/silcclient/README index 0fb6e0b4..499298db 100644 --- a/lib/silcclient/README +++ b/lib/silcclient/README @@ -42,18 +42,19 @@ for detailed definition of SilcClient object. `ops' can be defined for example as follows: SilcClientOperations ops = { - say: silc_say, - channel_message: silc_channel_message, - private_message: silc_private_message, - notify: silc_notify, - command: silc_command, - command_reply: silc_command_reply, - connect: silc_connect, - disconnect: silc_disconnect, - get_auth_method: silc_get_auth_method, - verify_public_key: silc_verify_public_key, - ask_passphrase: silc_ask_passphrase, - failure: silc_failure, + silc_say, + silc_channel_message, + silc_private_message, + silc_notify, + silc_command, + silc_command_reply, + silc_connect, + silc_disconnect, + silc_get_auth_method, + silc_verify_public_key, + silc_ask_passphrase, + silc_failure, + silc_key_agreement, }; diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 04790cdb..50445d00 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -778,6 +778,7 @@ void silc_client_packet_parse(SilcPacketParserContext *parser_context) /* Parse the packet */ +#if 0 /* If REKEY protocol is active we must proccess the packets synchronously since we must assure that incoming packets that are encrypted with the old key is processed before the new keys is set to use. */ @@ -786,6 +787,7 @@ void silc_client_packet_parse(SilcPacketParserContext *parser_context) (void *)parser_context, parser_context->sock->sock); else +#endif silc_task_register(client->timeout_queue, parser_context->sock->sock, silc_client_packet_parse_real, (void *)parser_context, 0, 1, diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index d9e856f5..13ebfd0b 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -85,7 +85,8 @@ struct SilcClientConnectionStruct { /* Keys and stuff negotiated in the SKE protocol */ SilcCipher send_key; SilcCipher receive_key; - SilcHmac hmac; + SilcHmac hmac_send; + SilcHmac hmac_receive; SilcHash hash; /* Client ID and Channel ID cache. Messages transmitted in SILC network diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 29880be4..62396c5f 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -100,7 +100,7 @@ void silc_client_send_channel_message(SilcClient client, /* Get data used in packet header encryption, keys and stuff. */ cipher = conn->send_key; - hmac = conn->hmac; + hmac = conn->hmac_send; id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL); /* Set the packet context pointers. The destination ID is always diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index 06f0555a..45550516 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -69,7 +69,7 @@ void silc_client_send_private_message(SilcClient client, /* Get data used in the encryption */ cipher = client_entry->send_key; - hmac = conn->hmac; + hmac = conn->hmac_send; /* Set the packet context pointers. */ packetdata.flags = SILC_PACKET_FLAG_PRIVMSG_KEY; diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index a6ced2c0..cedf5767 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -128,8 +128,9 @@ void silc_client_protocol_ke_set_keys(SilcSKE ske, conn->rekey->ske_group = silc_ske_group_get_number(group); /* Save HMAC key to be used in the communication. */ - silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac); - silc_hmac_set_key(conn->hmac, keymat->hmac_key, keymat->hmac_key_len); + silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac_send); + silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, keymat->hmac_key_len); + conn->hmac_receive = conn->hmac_send; /* Save the HASH function */ silc_hash_alloc(hash->hash->name, &conn->hash); @@ -635,51 +636,70 @@ static void silc_client_protocol_rekey_validate(SilcClient client, SilcClientRekeyInternalContext *ctx, SilcSocketConnection sock, - SilcSKEKeyMaterial *keymat) + SilcSKEKeyMaterial *keymat, + bool send) { SilcClientConnection conn = (SilcClientConnection)sock->user_data; if (ctx->responder == TRUE) { - silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, - keymat->enc_key_len); - silc_cipher_set_iv(conn->send_key, keymat->receive_iv); - silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, - keymat->enc_key_len); - silc_cipher_set_iv(conn->receive_key, keymat->send_iv); + if (send) { + silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, + keymat->enc_key_len); + silc_cipher_set_iv(conn->send_key, keymat->receive_iv); + } else { + silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, + keymat->enc_key_len); + silc_cipher_set_iv(conn->receive_key, keymat->send_iv); + } } else { - silc_cipher_set_key(conn->send_key, keymat->send_enc_key, - keymat->enc_key_len); - silc_cipher_set_iv(conn->send_key, keymat->send_iv); - silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, - keymat->enc_key_len); - silc_cipher_set_iv(conn->receive_key, keymat->receive_iv); + if (send) { + silc_cipher_set_key(conn->send_key, keymat->send_enc_key, + keymat->enc_key_len); + silc_cipher_set_iv(conn->send_key, keymat->send_iv); + } else { + silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, + keymat->enc_key_len); + silc_cipher_set_iv(conn->receive_key, keymat->receive_iv); + } } - silc_hmac_set_key(conn->hmac, keymat->hmac_key, keymat->hmac_key_len); + if (send) { + silc_hmac_alloc(conn->hmac_receive->hmac->name, NULL, &conn->hmac_send); + silc_hmac_set_key(conn->hmac_send, keymat->hmac_key, + keymat->hmac_key_len); + } else { + silc_hmac_free(conn->hmac_receive); + conn->hmac_receive = conn->hmac_send; + } /* Save the current sending encryption key */ - memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len); - silc_free(conn->rekey->send_enc_key); - conn->rekey->send_enc_key = - silc_calloc(keymat->enc_key_len / 8, - sizeof(*conn->rekey->send_enc_key)); - memcpy(conn->rekey->send_enc_key, keymat->send_enc_key, - keymat->enc_key_len / 8); - conn->rekey->enc_key_len = keymat->enc_key_len / 8; + if (!send) { + memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len); + silc_free(conn->rekey->send_enc_key); + conn->rekey->send_enc_key = + silc_calloc(keymat->enc_key_len / 8, + sizeof(*conn->rekey->send_enc_key)); + memcpy(conn->rekey->send_enc_key, keymat->send_enc_key, + keymat->enc_key_len / 8); + conn->rekey->enc_key_len = keymat->enc_key_len / 8; + } } /* This function actually re-generates (when not using PFS) the keys and takes them into use. */ -void silc_client_protocol_rekey_generate(SilcClient client, - SilcClientRekeyInternalContext *ctx) +static void +silc_client_protocol_rekey_generate(SilcClient client, + SilcClientRekeyInternalContext *ctx, + bool send) { SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data; SilcSKEKeyMaterial *keymat; uint32 key_len = silc_cipher_get_key_len(conn->send_key); uint32 hash_len = conn->hash->hash->hash_len; - SILC_LOG_DEBUG(("Generating new session keys (no PFS)")); + SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)", + send ? "sending" : "receiving")); /* Generate the new key */ keymat = silc_calloc(1, sizeof(*keymat)); @@ -689,7 +709,7 @@ void silc_client_protocol_rekey_generate(SilcClient client, conn->hash, keymat); /* Set the keys into use */ - silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat); + silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send); silc_ske_free_key_material(keymat); } @@ -697,9 +717,10 @@ void silc_client_protocol_rekey_generate(SilcClient client, /* This function actually re-generates (with PFS) the keys and takes them into use. */ -void +static void silc_client_protocol_rekey_generate_pfs(SilcClient client, - SilcClientRekeyInternalContext *ctx) + SilcClientRekeyInternalContext *ctx, + bool send) { SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data; SilcSKEKeyMaterial *keymat; @@ -708,7 +729,8 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client, unsigned char *tmpbuf; uint32 klen; - SILC_LOG_DEBUG(("Generating new session keys (with PFS)")); + SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)", + send ? "sending" : "receiving")); /* Encode KEY to binary data */ tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen); @@ -719,7 +741,7 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client, conn->hash, keymat); /* Set the keys into use */ - silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat); + silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send); memset(tmpbuf, 0, klen); silc_free(tmpbuf); @@ -741,8 +763,8 @@ silc_client_protocol_rekey_send_packet(SilcSKE ske, SilcClient client = (SilcClient)ctx->client; /* Send the packet immediately */ - silc_client_packet_send_flush(client, ctx->sock, type, NULL, 0, NULL, NULL, - packet->data, packet->len); + silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL, + packet->data, packet->len, FALSE); } /* Performs re-key as defined in the SILC protocol specification. */ @@ -815,9 +837,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) */ /* Send the REKEY_DONE to indicate we will take new keys into use */ - silc_client_packet_send_flush(client, ctx->sock, - SILC_PACKET_REKEY_DONE, - NULL, 0, NULL, NULL, NULL, 0); + silc_client_packet_send(client, ctx->sock, + SILC_PACKET_REKEY_DONE, + NULL, 0, NULL, NULL, NULL, 0, FALSE); + + /* After we send REKEY_DONE we must set the sending encryption + key to the new key since all packets after this packet must + encrypted with the new key. */ + silc_client_protocol_rekey_generate(client, ctx, TRUE); /* The protocol ends in next stage. */ protocol->state = SILC_PROTOCOL_STATE_END; @@ -829,8 +856,8 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) */ /* Start the re-key by sending the REKEY packet */ - silc_client_packet_send_flush(client, ctx->sock, SILC_PACKET_REKEY, - NULL, 0, NULL, NULL, NULL, 0); + silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY, + NULL, 0, NULL, NULL, NULL, 0, FALSE); if (ctx->pfs == TRUE) { /* @@ -867,9 +894,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) /* Send the REKEY_DONE to indicate we will take new keys into use now. */ - silc_client_packet_send_flush(client, ctx->sock, - SILC_PACKET_REKEY_DONE, - NULL, 0, NULL, NULL, NULL, 0); + silc_client_packet_send(client, ctx->sock, + SILC_PACKET_REKEY_DONE, + NULL, 0, NULL, NULL, NULL, 0, FALSE); + + /* After we send REKEY_DONE we must set the sending encryption + key to the new key since all packets after this packet must + encrypted with the new key. */ + silc_client_protocol_rekey_generate(client, ctx, TRUE); /* The protocol ends in next stage. */ protocol->state = SILC_PROTOCOL_STATE_END; @@ -932,9 +964,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) /* Send the REKEY_DONE to indicate we will take new keys into use now. */ - silc_client_packet_send_flush(client, ctx->sock, SILC_PACKET_REKEY_DONE, - NULL, 0, NULL, NULL, NULL, 0); + silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE, + NULL, 0, NULL, NULL, NULL, 0, FALSE); + /* After we send REKEY_DONE we must set the sending encryption + key to the new key since all packets after this packet must + encrypted with the new key. */ + silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE); + /* The protocol ends in next stage. */ protocol->state = SILC_PROTOCOL_STATE_END; break; @@ -950,6 +987,10 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0); } + /* We received the REKEY_DONE packet and all packets after this is + encrypted with the new key so set the decryption key to the new key */ + silc_client_protocol_rekey_generate(client, ctx, FALSE); + /* Protocol has ended, call the final callback */ if (protocol->final_callback) protocol->execute_final(client->timeout_queue, 0, protocol, fd); diff --git a/lib/silcclient/protocol.h b/lib/silcclient/protocol.h index 71e25069..e55f4c66 100644 --- a/lib/silcclient/protocol.h +++ b/lib/silcclient/protocol.h @@ -104,10 +104,5 @@ void silc_client_protocol_ke_set_keys(SilcSKE ske, SilcHash hash, SilcHmac hmac, SilcSKEDiffieHellmanGroup group); -void silc_client_protocol_rekey_generate(SilcClient client, - SilcClientRekeyInternalContext *ctx); -void -silc_client_protocol_rekey_generate_pfs(SilcClient client, - SilcClientRekeyInternalContext *ctx); #endif diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index 1708226e..0911ca06 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -403,8 +403,6 @@ void silc_packet_receive_process(SilcSocketConnection sock, parse_ctx->packet = silc_packet_context_alloc(); parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len); parse_ctx->sock = sock; - parse_ctx->cipher = cipher; - parse_ctx->hmac = hmac; parse_ctx->context = context; silc_buffer_pull_tail(parse_ctx->packet->buffer, diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index 30a9cc51..79248227 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -158,14 +158,6 @@ typedef struct { The associated connection. - SilcCipher cipher - - The cipher to be used in the decryption. - - SilcHmac hmac - - The HMAC to be used in the decryption. - void *context User context that is sent to the silc_packet_receive_process @@ -177,8 +169,6 @@ typedef struct { typedef struct { SilcPacketContext *packet; SilcSocketConnection sock; - SilcCipher cipher; - SilcHmac hmac; void *context; } SilcPacketParserContext; -- 2.24.0