X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcske%2Fpayload.c;h=d7fb301d5e514acfb0ff31626a026d87ee2e7313;hp=d9e89389ed29d4e9f03a0eac3efadd0567c483a8;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=a820923a77f9151a35b2ec61e954f3258e5c2816 diff --git a/lib/silcske/payload.c b/lib/silcske/payload.c index d9e89389..d7fb301d 100644 --- a/lib/silcske/payload.c +++ b/lib/silcske/payload.c @@ -1,16 +1,15 @@ /* - payload.c + payload.c Author: Pekka Riikonen - Copyright (C) 2000 - 2001 Pekka Riikonen + Copyright (C) 2000 - 2002 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - + the Free Software Foundation; version 2 of the License. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -36,8 +35,9 @@ SilcSKEStatus silc_ske_payload_start_encode(SilcSKE ske, if (!payload) return SILC_SKE_STATUS_ERROR; - buf = silc_buffer_alloc(payload->len); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(payload->len); + if (!buf) + return SILC_SKE_STATUS_OUT_OF_MEMORY; /* Encode the payload */ ret = silc_buffer_format(buf, @@ -99,6 +99,8 @@ silc_ske_payload_start_decode(SilcSKE ske, SILC_LOG_HEXDUMP(("KE Start Payload"), buffer->data, buffer->len); payload = silc_calloc(1, sizeof(*payload)); + if (!payload) + return SILC_SKE_STATUS_OUT_OF_MEMORY; payload->cookie_len = SILC_SKE_COOKIE_LEN; /* Parse start of the payload */ @@ -125,22 +127,33 @@ silc_ske_payload_start_decode(SilcSKE ske, &payload->comp_alg_len), SILC_STR_END); if (ret == -1) { - status = SILC_SKE_STATUS_ERROR; + SILC_LOG_ERROR(("Malformed KE Start Payload")); + status = SILC_SKE_STATUS_BAD_PAYLOAD; goto err; } if (tmp != 0) { - SILC_LOG_DEBUG(("Bad reserved field")); + SILC_LOG_ERROR(("Bad RESERVED field in KE Start Payload")); status = SILC_SKE_STATUS_BAD_RESERVED_FIELD; goto err; } if (payload->len != buffer->len) { - SILC_LOG_DEBUG(("Bad payload length")); + SILC_LOG_ERROR(("Garbage after KE Start Payload")); status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH; goto err; } + /* Check for mandatory fields */ + if (!payload->cookie || !payload->version_len || + !payload->ke_grp_len || !payload->pkcs_alg_len || + !payload->enc_alg_len || !payload->hash_alg_len || + !payload->hmac_alg_len) { + SILC_LOG_ERROR(("KE Start Payload is missing mandatory fields")); + status = SILC_SKE_STATUS_BAD_PAYLOAD; + goto err; + } + /* Return the payload */ *return_payload = payload; @@ -158,22 +171,14 @@ silc_ske_payload_start_decode(SilcSKE ske, void silc_ske_payload_start_free(SilcSKEStartPayload *payload) { if (payload) { - if (payload->cookie) - silc_free(payload->cookie); - if (payload->version) - silc_free(payload->version); - if (payload->ke_grp_list) - silc_free(payload->ke_grp_list); - if (payload->pkcs_alg_list) - silc_free(payload->pkcs_alg_list); - if (payload->enc_alg_list) - silc_free(payload->enc_alg_list); - if (payload->hash_alg_list) - silc_free(payload->hash_alg_list); - if (payload->hmac_alg_list) - silc_free(payload->hmac_alg_list); - if (payload->comp_alg_list) - silc_free(payload->comp_alg_list); + silc_free(payload->cookie); + silc_free(payload->version); + silc_free(payload->ke_grp_list); + silc_free(payload->pkcs_alg_list); + silc_free(payload->enc_alg_list); + silc_free(payload->hash_alg_list); + silc_free(payload->hmac_alg_list); + silc_free(payload->comp_alg_list); silc_free(payload); } } @@ -187,7 +192,7 @@ SilcSKEStatus silc_ske_payload_ke_encode(SilcSKE ske, { SilcBuffer buf; unsigned char *x_str; - uint32 x_len; + SilcUInt32 x_len; int ret; SILC_LOG_DEBUG(("Encoding KE Payload")); @@ -207,9 +212,10 @@ SilcSKEStatus silc_ske_payload_ke_encode(SilcSKE ske, /* Allocate channel payload buffer. The length of the buffer is 4 + public key + 2 + x + 2 + signature. */ - buf = silc_buffer_alloc(4 + payload->pk_len + 2 + x_len + - 2 + payload->sign_len); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(4 + payload->pk_len + 2 + x_len + + 2 + payload->sign_len); + if (!buf) + return SILC_SKE_STATUS_OUT_OF_MEMORY; /* Encode the payload */ ret = silc_buffer_format(buf, @@ -251,8 +257,8 @@ SilcSKEStatus silc_ske_payload_ke_decode(SilcSKE ske, SilcSKEStatus status = SILC_SKE_STATUS_ERROR; SilcSKEKEPayload *payload; unsigned char *x = NULL; - uint16 x_len; - uint32 tot_len = 0, len2; + SilcUInt16 x_len; + SilcUInt32 tot_len = 0, len2; int ret; SILC_LOG_DEBUG(("Decoding Key Exchange Payload")); @@ -260,6 +266,8 @@ SilcSKEStatus silc_ske_payload_ke_decode(SilcSKE ske, SILC_LOG_HEXDUMP(("KE Payload"), buffer->data, buffer->len); payload = silc_calloc(1, sizeof(*payload)); + if (!payload) + return SILC_SKE_STATUS_OUT_OF_MEMORY; len2 = buffer->len; @@ -269,11 +277,15 @@ SilcSKEStatus silc_ske_payload_ke_decode(SilcSKE ske, SILC_STR_UI_SHORT(&payload->pk_type), SILC_STR_END); if (ret == -1) { - status = SILC_SKE_STATUS_ERROR; + SILC_LOG_ERROR(("Cannot decode public key from KE payload")); + status = SILC_SKE_STATUS_BAD_PAYLOAD; goto err; } - if (payload->pk_type == 0) { + if (ske->start_payload && + ((payload->pk_type < SILC_SKE_PK_TYPE_SILC || + payload->pk_type > SILC_SKE_PK_TYPE_SPKI) || !payload->pk_len)) { + SILC_LOG_ERROR(("Malformed public key in KE payload")); status = SILC_SKE_STATUS_BAD_PAYLOAD; goto err; } @@ -290,14 +302,16 @@ SilcSKEStatus silc_ske_payload_ke_decode(SilcSKE ske, &payload->sign_len), SILC_STR_END); if (ret == -1) { - status = SILC_SKE_STATUS_ERROR; + SILC_LOG_ERROR(("Malformed KE Payload")); + status = SILC_SKE_STATUS_BAD_PAYLOAD; goto err; } tot_len += x_len + 2; tot_len += payload->sign_len + 2; - if (x_len < 3) { + if (x_len < 16) { + SILC_LOG_ERROR(("Too short DH value in KE Payload")); status = SILC_SKE_STATUS_BAD_PAYLOAD; goto err; } @@ -305,14 +319,15 @@ SilcSKEStatus silc_ske_payload_ke_decode(SilcSKE ske, if (ske->start_payload && (ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) && (payload->sign_len < 3 || !payload->sign_data)) { - SILC_LOG_DEBUG(("The signature data is missing - both parties are " + SILC_LOG_ERROR(("The signature data is missing - both parties are " "required to do authentication")); status = SILC_SKE_STATUS_BAD_PAYLOAD; goto err; } if (tot_len != len2) { - status = SILC_SKE_STATUS_BAD_PAYLOAD; + SILC_LOG_ERROR(("Garbage after KE payload")); + status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH; goto err; } @@ -328,12 +343,9 @@ SilcSKEStatus silc_ske_payload_ke_decode(SilcSKE ske, return SILC_SKE_STATUS_OK; err: - if (payload->pk_data) - silc_free(payload->pk_data); - if (payload->sign_data) - silc_free(payload->sign_data); - if (x) - silc_free(x); + silc_free(payload->pk_data); + silc_free(payload->sign_data); + silc_free(x); silc_free(payload); ske->status = status; return status; @@ -344,11 +356,9 @@ SilcSKEStatus silc_ske_payload_ke_decode(SilcSKE ske, void silc_ske_payload_ke_free(SilcSKEKEPayload *payload) { if (payload) { - if (payload->pk_data) - silc_free(payload->pk_data); + silc_free(payload->pk_data); silc_mp_uninit(&payload->x); - if (payload->sign_data) - silc_free(payload->sign_data); + silc_free(payload->sign_data); silc_free(payload); } }