From 54710b9a767eb2fa429f20839f053d16031b5a9d Mon Sep 17 00:00:00 2001 From: Jonathan Dieter Date: Thu, 31 May 2018 10:05:36 +0300 Subject: [PATCH] Fix problems with validating pre-supplied header checksum and length Signed-off-by: Jonathan Dieter --- include/zck.h | 2 +- src/lib/header.c | 22 +++++++++++++------ src/lib/zck.c | 57 +++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/include/zck.h b/include/zck.h index 24811e3..14b0d91 100644 --- a/include/zck.h +++ b/include/zck.h @@ -111,7 +111,7 @@ void zck_free(zckCtx **zck); * Options *******************************************************************/ /* Set string option */ -int zck_set_soption(zckCtx *zck, zck_soption option, const void *value, +int zck_set_soption(zckCtx *zck, zck_soption option, const char *value, size_t length) __attribute__ ((warn_unused_result)); /* Set integer option */ diff --git a/src/lib/header.c b/src/lib/header.c index b727b97..372ae4d 100644 --- a/src/lib/header.c +++ b/src/lib/header.c @@ -113,12 +113,6 @@ int read_lead_1(zckCtx *zck) { size_t header_length = 0; if(!compint_to_size(&header_length, header+length, &length, lead)) return False; - if(zck->prep_hdr_size > -1 && (size_t)zck->prep_hdr_size != header_length) { - zck_log(ZCK_LOG_ERROR, - "Header length (%lu) doesn't match requested header length " - "(%lu)\n", header_length, zck->prep_hdr_size); - return False; - } zck->header_length = header_length; zck->header = header; @@ -145,6 +139,8 @@ int read_lead_2(zckCtx *zck) { /* Read header digest */ zck_log(ZCK_LOG_DEBUG, "Reading header digest\n"); header = realloc(header, length + zck->hash_type.digest_size); + zck->lead_string = header; + zck->header = header; if(header == NULL) { zck_log(ZCK_LOG_ERROR, "Unable to re-allocate %lu bytes\n", length + zck->hash_type.digest_size); @@ -160,7 +156,10 @@ int read_lead_2(zckCtx *zck) { if(zck->prep_digest && memcmp(zck->prep_digest, header + length, zck->hash_type.digest_size) != 0) { zck_log(ZCK_LOG_ERROR, - "Header digest doesn't match requested header digest\n"); + "Header digest doesn't match requested header digest\n" + "Expected: %s\nActual: %s\n", + get_digest_string(zck->prep_digest, zck->hash_type.digest_size), + get_digest_string(header + length, zck->hash_type.digest_size)); return False; } zck->header_digest = zmalloc(zck->hash_type.digest_size); @@ -172,6 +171,15 @@ int read_lead_2(zckCtx *zck) { memcpy(zck->header_digest, header + length, zck->hash_type.digest_size); length += zck->hash_type.digest_size; + /* Check whether full header length matches specified header length */ + if(zck->prep_hdr_size > -1 && + (size_t)zck->prep_hdr_size != zck->header_length + length) { + zck_log(ZCK_LOG_ERROR, + "Header length (%lu) doesn't match requested header length " + "(%lu)\n", zck->header_length + length, + zck->prep_hdr_size); + return False; + } /* Store pre-header */ zck->header = header; zck->header_size = lead; diff --git a/src/lib/zck.c b/src/lib/zck.c index 4279f3b..8e7eaea 100644 --- a/src/lib/zck.c +++ b/src/lib/zck.c @@ -110,37 +110,78 @@ int PUBLIC zck_set_ioption(zckCtx *zck, zck_ioption option, ssize_t value) { return True; } -int PUBLIC zck_set_soption(zckCtx *zck, zck_soption option, const void *value, +int hex_to_int (char c) { + if (c >= 97) + c = c - 32; + int result = (c / 16 - 3) * 10 + (c % 16); + if (result > 9) + result--; + return result; +} + +char *ascii_checksum_to_bin (char *checksum) { + int cl = strlen(checksum); + char *raw_checksum = zmalloc(cl/2); + if(raw_checksum == NULL) { + zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", cl/2); + return NULL; + } + char *rp = raw_checksum; + int buf = 0; + for (int i=0; iprep_hash_type < 0) { + free(data); zck_log(ZCK_LOG_ERROR, "For validation, you must set the header hash type " "*before* the header digest itself\n"); return False; } - if(!zck_hash_setup(&chk_type, zck->prep_hash_type)) + if(!zck_hash_setup(&chk_type, zck->prep_hash_type)) { + free(data); return False; - if(chk_type.digest_size != length) { + } + if(chk_type.digest_size != length/2) { + free(data); zck_log(ZCK_LOG_ERROR, "Hash digest size mismatch for header " "validation\n" "Expected: %lu\nProvided: %lu\n", chk_type.digest_size, - length); + length/2); return False; } - zck->prep_digest = zmalloc(length); - memcpy(zck->prep_digest, value, length); + zck->prep_digest = ascii_checksum_to_bin(data); + free(data); /* Compression options */ } else if(option < 2000) { VALIDATE_WRITE(zck); - return comp_soption(zck, option, value, length); + return comp_soption(zck, option, data, length); /* Unknown options */ } else { + free(data); zck_log(ZCK_LOG_ERROR, "Unknown string option %i\n", option); return False; } @@ -406,9 +447,9 @@ int zck_import_dict(zckCtx *zck) { zck_log(ZCK_LOG_DEBUG, "Setting dict\n"); if(!comp_soption(zck, ZCK_COMP_DICT, data, size)) return False; - free(data); if(!zck_comp_init(zck)) return False; + free(data); return True; } -- 2.30.2