From a4ae0399a208d975bc9034b4a796d4fcf1b748a1 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 19 Nov 2005 18:41:06 +0000 Subject: [PATCH] Check that ctx->packet is valid in protocols. Crashbug fix. --- CHANGES | 5 +++ apps/silcd/protocol.c | 71 +++++++++++++++++++++++++++++++++++++++ lib/silcclient/protocol.c | 53 +++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) diff --git a/CHANGES b/CHANGES index f40e2a1d..4753229a 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,11 @@ Sat Nov 19 17:34:51 EET 2005 Pekka Riikonen * Added SilcMime API to lib/silcutil/silcmime.[ch]. The old silc_mime_parse is available but deprecated. + * Check that packet is valid when processing key exchange, + authentication and rekey protocols. Fixes a crashbug. + Affected files are apps/silcd/protocol.c and + lib/silcclient/protocol.c. + Wed Nov 16 15:47:12 EET 2005 Pekka Riikonen * Added SHA-256 to crypto library. The SHA-256 takes now diff --git a/apps/silcd/protocol.c b/apps/silcd/protocol.c index 06e80fd4..20525e58 100644 --- a/apps/silcd/protocol.c +++ b/apps/silcd/protocol.c @@ -436,6 +436,16 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) silc_ske_check_version, context); if (ctx->responder == TRUE) { + if (!ctx->packet) { + SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)", + silc_ske_map_status(status), ctx->sock->hostname, + ctx->sock->ip)); + + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, server->schedule, 0, 300000); + return; + } + /* Start the key exchange by processing the received security properties packet from initiator. */ SILC_LOG_DEBUG(("Process security property list (KE)")); @@ -488,6 +498,16 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) SILC_LOG_DEBUG(("Send security property list reply (KE)")); status = silc_ske_responder_phase_1(ctx->ske); } else { + if (!ctx->packet) { + SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)", + silc_ske_map_status(status), ctx->sock->hostname, + ctx->sock->ip)); + + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, server->schedule, 0, 300000); + return; + } + /* Call Phase-1 function. This processes the Key Exchange Start paylaod reply we just got from the responder. The callback function will receive the processed payload where we will @@ -522,6 +542,16 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) * Phase 2 */ if (ctx->responder == TRUE) { + if (!ctx->packet) { + SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)", + silc_ske_map_status(status), ctx->sock->hostname, + ctx->sock->ip)); + + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, server->schedule, 0, 300000); + return; + } + /* Process the received Key Exchange 1 Payload packet from the initiator. This also creates our parts of the Diffie Hellman algorithm. The silc_server_protocol_ke_continue @@ -572,6 +602,16 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) /* End the protocol on the next round */ protocol->state = SILC_PROTOCOL_STATE_END; } else { + if (!ctx->packet) { + SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)", + silc_ske_map_status(status), ctx->sock->hostname, + ctx->sock->ip)); + + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, server->schedule, 0, 300000); + return; + } + /* Finish the protocol. This verifies the Key Exchange 2 payload sent by responder. The silc_server_protocol_ke_continue will be called after the public key has been verified. */ @@ -892,6 +932,13 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth) SILC_LOG_INFO(("Performing authentication protocol for %s (%s)", ctx->sock->hostname, ctx->sock->ip)); + if (!ctx->packet) { + SILC_LOG_ERROR(("Bad authentication protocol request")); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, server->schedule, 0, 300000); + return; + } + /* Parse the received authentication data packet. The received payload is Connection Auth Payload. */ ret = silc_buffer_unformat(ctx->packet->buffer, @@ -1360,6 +1407,14 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey) * using the SKE protocol. */ + if (!ctx->packet) { + SILC_LOG_ERROR(("Error during Re-key, with %s (%s)", + ctx->sock->hostname, ctx->sock->ip)); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, server->schedule, 0, 300000); + return; + } + if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) { SILC_LOG_ERROR(("Error during Re-key (R PFS): re-key state is " "incorrect (received %d, expected %d packet), " @@ -1501,6 +1556,14 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey) /* * The packet type must be KE packet */ + if (!ctx->packet) { + SILC_LOG_ERROR(("Error during Re-key, with %s (%s)", + ctx->sock->hostname, ctx->sock->ip)); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, server->schedule, 0, 300000); + return; + } + if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) { SILC_LOG_ERROR(("Error during Re-key (I PFS): re-key state is " "incorrect (received %d, expected %d packet), " @@ -1545,6 +1608,14 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey) * End protocol */ + if (!ctx->packet) { + SILC_LOG_ERROR(("Error during Re-key, with %s (%s)", + ctx->sock->hostname, ctx->sock->ip)); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, server->schedule, 0, 300000); + return; + } + if (ctx->packet->type != SILC_PACKET_REKEY_DONE) { SILC_LOG_ERROR(("Error during Re-key (%s PFS): re-key state is " "incorrect (received %d, expected %d packet), " diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index b3cbe4a5..9d9918a0 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -284,6 +284,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange) context); if (ctx->responder == TRUE) { + if (!ctx->packet) { + SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol", + status)); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, client->schedule, 0, 0); + return; + } + /* Start the key exchange by processing the received security properties packet from initiator. */ status = @@ -335,6 +343,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange) /* Sends the selected security properties to the initiator. */ status = silc_ske_responder_phase_1(ctx->ske); } else { + if (!ctx->packet) { + SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol", + status)); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, client->schedule, 0, 0); + return; + } + /* Call Phase-1 function. This processes the Key Exchange Start paylaod reply we just got from the responder. The callback function will receive the processed payload where we will @@ -365,6 +381,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange) * Phase 2 */ if (ctx->responder == TRUE) { + if (!ctx->packet) { + SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol", + status)); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, client->schedule, 0, 0); + return; + } + /* Process the received Key Exchange 1 Payload packet from the initiator. This also creates our parts of the Diffie Hellman algorithm. The silc_client_protocol_ke_continue will @@ -413,6 +437,14 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange) /* End the protocol on the next round */ protocol->state = SILC_PROTOCOL_STATE_END; } else { + if (!ctx->packet) { + SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol", + status)); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, client->schedule, 0, 0); + return; + } + /* Finish the protocol. This verifies the Key Exchange 2 payload sent by responder. The silc_client_protocol_ke_continue will be called after the public key has been verified. */ @@ -899,6 +931,13 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) * using the SKE protocol. */ + if (!ctx->packet) { + SILC_LOG_WARNING(("Error during Re-key")); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, client->schedule, 0, 300000); + return; + } + if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) { /* Error in protocol */ protocol->state = SILC_PROTOCOL_STATE_ERROR; @@ -1038,6 +1077,13 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) /* * The packet type must be KE packet */ + if (!ctx->packet) { + SILC_LOG_WARNING(("Error during Re-key")); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, client->schedule, 0, 300000); + return; + } + if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) { /* Error in protocol */ protocol->state = SILC_PROTOCOL_STATE_ERROR; @@ -1077,6 +1123,13 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) * End protocol */ + if (!ctx->packet) { + SILC_LOG_WARNING(("Error during Re-key")); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute(protocol, client->schedule, 0, 300000); + return; + } + if (ctx->packet->type != SILC_PACKET_REKEY_DONE) { /* Error in protocol */ protocol->state = SILC_PROTOCOL_STATE_ERROR; -- 2.43.0