From: Pekka Riikonen Date: Tue, 26 Jun 2001 21:16:17 +0000 (+0000) Subject: updates. X-Git-Tag: robodoc-323~123 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=a242db4691e6b9a6750af4f14b0f2697a7774435 updates. --- diff --git a/CHANGES b/CHANGES index 9c06a577..9ef4147d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,21 @@ +Wed Jun 27 00:10:33 EEST 2001 Pekka Riikonen + + * Fixed a fatal bug in private message sending and reception + encryption and decryption when using private message keys. + The implementation was incorrect and did not follow the + specification. It causd that some of the message were + lost since it did not use the sending and receiving keys + as the protocol suggests. This has been fixed and will cause + incompatibilities with older clients when sending private + message encrypted with private message keys. Affected files + lib/silcclient/client_prvmsg.c, lib/silcclient/client_keyagr.c + and various other in Irssi SILC Client. + + Added `responder' boolean argument to the functions + silc_client_add_private_message_key[_ske] to indicate when + the key is added as responder or initiator of the key + negotiation. + Tue Jun 26 19:23:07 EEST 2001 Pekka Riikonen * Removed the silc_ske_check_version function and created @@ -20,6 +38,11 @@ Tue Jun 26 19:23:07 EEST 2001 Pekka Riikonen is in process when we get timeout. Affected file is lib/silcclient/client_keyagr.c. + * Do not resolve the client ID forever if it returns in the + first time that such client does not exist. This was done + for example with private message. Affected file is + lib/silcclient/client_prvmsg.c. + Mon Jun 25 21:42:51 EEST 2001 Pekka Riikonen * Do not add regex.h for WIN32. The affected file diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index cf3fc6ba..ead74959 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -688,6 +688,7 @@ static void command_away(const char *data, SILC_SERVER_REC *server, typedef struct { int type; /* 1 = msg, 2 = channel */ + bool responder; SILC_SERVER_REC *server; } *KeyInternal; @@ -717,7 +718,7 @@ static void keyagr_completion(SilcClient client, /* Set the private key for this client */ silc_client_del_private_message_key(client, conn, client_entry); silc_client_add_private_message_key_ske(client, conn, client_entry, - NULL, key); + NULL, key, i->responder); printformat_module("fe-common/silc", i->server, NULL, MSGLEVEL_NOTICES, SILCTXT_KEY_AGREEMENT_PRIVMSG, client_entry->nickname); @@ -889,13 +890,13 @@ static void command_key(const char *data, SILC_SERVER_REC *server, argv[5], argv[4], argv_lens[4], (argv[4][0] == '*' ? - TRUE : FALSE)); + TRUE : FALSE), FALSE); else silc_client_add_private_message_key(silc_client, conn, client_entry, NULL, argv[4], argv_lens[4], (argv[4][0] == '*' ? - TRUE : FALSE)); + TRUE : FALSE), FALSE); /* Send the key to the remote client so that it starts using it too. */ @@ -1135,14 +1136,18 @@ static void command_key(const char *data, SILC_SERVER_REC *server, if (command == 4 && client_entry) { printformat_module("fe-common/silc", server, NULL, MSGLEVEL_NOTICES, SILCTXT_KEY_AGREEMENT, argv[2]); + internal->responder = TRUE; silc_client_send_key_agreement(silc_client, conn, client_entry, hostname, port, 120, keyagr_completion, internal); + if (!hostname) + silc_free(internal); goto out; } if (command == 5 && client_entry && hostname) { printformat_module("fe-common/silc", server, NULL, MSGLEVEL_NOTICES, SILCTXT_KEY_AGREEMENT_NEGOTIATE, argv[2]); + internal->responder = FALSE; silc_client_perform_key_agreement(silc_client, conn, client_entry, hostname, port, keyagr_completion, internal); diff --git a/lib/silcclient/client_keyagr.c b/lib/silcclient/client_keyagr.c index 1540b9dc..6be73f89 100644 --- a/lib/silcclient/client_keyagr.c +++ b/lib/silcclient/client_keyagr.c @@ -283,6 +283,10 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_timeout) If remote side decides to ignore the request the `completion' will be called after the specified timeout, `timeout_secs'. + NOTE: If the `hostname' and the `port' was not provided the `completion' + will not be called at all since this does nothing more than sending + a packet to the remote host. + NOTE: There can be only one active key agreement for one client entry. Before setting new one, the old one must be finished (it is finished after calling the completion callback) or the function diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index c5a41b11..5b465df2 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -126,6 +126,11 @@ static void silc_client_private_message_cb(SilcClient client, { SilcPacketContext *packet = (SilcPacketContext *)context; + if (!clients) { + silc_packet_context_free(packet); + return; + } + silc_client_private_message(client, conn->sock, packet); silc_packet_context_free(packet); } @@ -168,7 +173,7 @@ void silc_client_private_message(SilcClient client, /* Parse the payload and decrypt it also if private message key is set */ payload = silc_private_message_payload_parse(packet->buffer, - remote_client->send_key); + remote_client->receive_key); if (!payload) { silc_free(remote_id); return; @@ -233,7 +238,7 @@ static void silc_client_private_message_key_cb(SilcClient client, /* Now take the key in use */ if (!silc_client_add_private_message_key(client, conn, clients[0], - cipher, key, key_len, FALSE)) + cipher, key, key_len, FALSE, TRUE)) goto out; /* Print some info for application */ @@ -282,6 +287,11 @@ void silc_client_private_message_key(SilcClient client, requirements of the SILC protocol are met. The API, however, allows to allocate any cipher. + If `responder' is TRUE then the sending and receiving keys will be + set according the client being the receiver of the private key. If + FALSE the client is being the sender (or negotiator) of the private + key. + It is not necessary to set key for normal private message usage. If the key is not set then the private messages are encrypted using normal session keys. Setting the private key, however, increases the security. @@ -295,7 +305,8 @@ int silc_client_add_private_message_key(SilcClient client, char *cipher, unsigned char *key, uint32 key_len, - int generate_key) + bool generate_key, + bool responder) { unsigned char private_key[32]; uint32 len; @@ -341,12 +352,21 @@ int silc_client_add_private_message_key(SilcClient client, silc_cipher_alloc(cipher, &client_entry->receive_key); /* Set the keys */ - silc_cipher_set_key(client_entry->send_key, keymat->send_enc_key, - keymat->enc_key_len); - silc_cipher_set_iv(client_entry->send_key, keymat->send_iv); - silc_cipher_set_key(client_entry->receive_key, keymat->receive_enc_key, - keymat->enc_key_len); - silc_cipher_set_iv(client_entry->receive_key, keymat->receive_iv); + if (responder == TRUE) { + silc_cipher_set_key(client_entry->send_key, keymat->receive_enc_key, + keymat->enc_key_len); + silc_cipher_set_iv(client_entry->send_key, keymat->receive_iv); + silc_cipher_set_key(client_entry->receive_key, keymat->send_enc_key, + keymat->enc_key_len); + silc_cipher_set_iv(client_entry->receive_key, keymat->send_iv); + } else { + silc_cipher_set_key(client_entry->send_key, keymat->send_enc_key, + keymat->enc_key_len); + silc_cipher_set_iv(client_entry->send_key, keymat->send_iv); + silc_cipher_set_key(client_entry->receive_key, keymat->receive_enc_key, + keymat->enc_key_len); + silc_cipher_set_iv(client_entry->receive_key, keymat->receive_iv); + } /* Free the key material */ silc_ske_free_key_material(keymat); @@ -364,7 +384,8 @@ int silc_client_add_private_message_key_ske(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, char *cipher, - SilcSKEKeyMaterial *key) + SilcSKEKeyMaterial *key, + bool responder) { assert(client_entry); @@ -384,12 +405,21 @@ int silc_client_add_private_message_key_ske(SilcClient client, silc_cipher_alloc(cipher, &client_entry->receive_key); /* Set the keys */ - silc_cipher_set_key(client_entry->send_key, key->send_enc_key, - key->enc_key_len); - silc_cipher_set_iv(client_entry->send_key, key->send_iv); - silc_cipher_set_key(client_entry->receive_key, key->receive_enc_key, - key->enc_key_len); - silc_cipher_set_iv(client_entry->receive_key, key->receive_iv); + if (responder == TRUE) { + silc_cipher_set_key(client_entry->send_key, key->receive_enc_key, + key->enc_key_len); + silc_cipher_set_iv(client_entry->send_key, key->receive_iv); + silc_cipher_set_key(client_entry->receive_key, key->send_enc_key, + key->enc_key_len); + silc_cipher_set_iv(client_entry->receive_key, key->send_iv); + } else { + silc_cipher_set_key(client_entry->send_key, key->send_enc_key, + key->enc_key_len); + silc_cipher_set_iv(client_entry->send_key, key->send_iv); + silc_cipher_set_key(client_entry->receive_key, key->receive_enc_key, + key->enc_key_len); + silc_cipher_set_iv(client_entry->receive_key, key->receive_iv); + } return TRUE; } diff --git a/lib/silcclient/silcapi.h b/lib/silcclient/silcapi.h index c1f46d25..45506527 100644 --- a/lib/silcclient/silcapi.h +++ b/lib/silcclient/silcapi.h @@ -910,7 +910,8 @@ void silc_client_command_pending(SilcClientConnection conn, * char *cipher, * unsigned char *key, * uint32 key_len, - * int generate_key); + * bool generate_key, + * bool responder); * * DESCRIPTION * @@ -923,6 +924,11 @@ void silc_client_command_pending(SilcClientConnection conn, * requirements of the SILC protocol are met. The API, however, allows * to allocate any cipher. * + * If `responder' is TRUE then the sending and receiving keys will be + * set according the client being the receiver of the private key. If + * FALSE the client is being the sender (or negotiator) of the private + * key. + * * It is not necessary to set key for normal private message usage. If the * key is not set then the private messages are encrypted using normal * session keys. Setting the private key, however, increases the security. @@ -937,7 +943,8 @@ int silc_client_add_private_message_key(SilcClient client, char *cipher, unsigned char *key, uint32 key_len, - int generate_key); + bool generate_key, + bool responder); /****f* silcclient/SilcClientAPI/silc_client_add_private_message_key_ske * @@ -951,18 +958,19 @@ int silc_client_add_private_message_key(SilcClient client, * * DESCRIPTION * - * Same as above but takes the key material from the SKE key material - * structure. This structure is received if the application uses the - * silc_client_send_key_agreement to negotiate the key material. The - * `cipher' SHOULD be provided as it is negotiated also in the SKE - * protocol. + * Same as silc_client_add_private_message_key but takes the key material + * from the SKE key material structure. This structure is received if + * the application uses the silc_client_send_key_agreement to negotiate + * the key material. The `cipher' SHOULD be provided as it is negotiated + * also in the SKE protocol. * ***/ int silc_client_add_private_message_key_ske(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, char *cipher, - SilcSKEKeyMaterial *key); + SilcSKEKeyMaterial *key, + bool responder); /****f* silcclient/SilcClientAPI/silc_client_send_private_message_key * @@ -1238,6 +1246,10 @@ void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys, * If remote side decides to ignore the request the `completion' will be * called after the specified timeout, `timeout_secs'. * + * NOTE: If the `hostname' and the `port' was not provided the `completion' + * will not be called at all since this does nothing more than sending + * a packet to the remote host. + * * NOTE: There can be only one active key agreement for one client entry. * Before setting new one, the old one must be finished (it is finished * after calling the completion callback) or the function diff --git a/lib/silccore/silcprivate.c b/lib/silccore/silcprivate.c index 48a31b65..c828a8f7 100644 --- a/lib/silccore/silcprivate.c +++ b/lib/silccore/silcprivate.c @@ -61,8 +61,10 @@ silc_private_message_payload_parse(SilcBuffer buffer, SilcCipher cipher) SILC_STR_UI16_NSTRING_ALLOC(&new->message, &new->message_len), SILC_STR_END); - if (ret == -1) + if (ret == -1) { + SILC_LOG_ERROR(("Incorrect private message payload")); goto err; + } if ((new->message_len < 1 || new->message_len > buffer->len)) { SILC_LOG_ERROR(("Incorrect private message payload in packet, "