Fixed winzip aes encryption with zero byte files.

Allow greater buffer to be passed in for hashing functions.
Fixed crc32 values not being stored in zip.
When reading zip get best hash to test against in signature.
Fixed formatting.
This commit is contained in:
Nathan Moinvaziri 2018-10-26 20:00:52 -07:00
parent 2ed269e000
commit 915c513abe
14 changed files with 220 additions and 93 deletions

View file

@ -4,9 +4,6 @@ matrix:
include:
- os: windows
compiler: clang
- os: windows
compiler: clang
env: TOOL="-DUSE_PKCRYPT=OFF -DUSE_AES=OFF"
- os: windows
compiler: gcc
- os: linux

1
mz.h
View file

@ -117,6 +117,7 @@ extern "C" {
#define MZ_HASH_SHA1_SIZE (20)
#define MZ_HASH_SHA256 (23)
#define MZ_HASH_SHA256_SIZE (32)
#define MZ_HASH_MAX_SIZE (256)
// MZ_UTILITY
#define MZ_UNUSED(SYMBOL) ((void)SYMBOL)

View file

@ -151,13 +151,13 @@ int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size)
if (sha->algorithm == MZ_HASH_SHA1)
{
if (digest_size != MZ_HASH_SHA1_SIZE)
if (digest_size < MZ_HASH_SHA1_SIZE)
return MZ_BUF_ERROR;
sha1_end(digest, &sha->ctx1);
}
else
{
if (digest_size != MZ_HASH_SHA256_SIZE)
if (digest_size < MZ_HASH_SHA256_SIZE)
return MZ_BUF_ERROR;
sha256_end(digest, &sha->ctx256);
}
@ -361,13 +361,13 @@ int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size)
if (hmac->algorithm == MZ_HASH_SHA1)
{
if (digest_size != MZ_HASH_SHA1_SIZE)
if (digest_size < MZ_HASH_SHA1_SIZE)
return MZ_BUF_ERROR;
hmac_sha_end(digest, digest_size, &hmac->ctx);
}
else
{
if (digest_size != MZ_HASH_SHA256_SIZE)
if (digest_size < MZ_HASH_SHA256_SIZE)
return MZ_BUF_ERROR;
hmac_sha_end(digest, digest_size, &hmac->ctx);
}

View file

@ -123,13 +123,13 @@ int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size)
if (sha->algorithm == MZ_HASH_SHA1)
{
if (digest_size != MZ_HASH_SHA1_SIZE)
if (digest_size < MZ_HASH_SHA1_SIZE)
return MZ_BUF_ERROR;
result = SHA1_Final(digest, &sha->ctx1);
}
else
{
if (digest_size != MZ_HASH_SHA256_SIZE)
if (digest_size < MZ_HASH_SHA256_SIZE)
return MZ_BUF_ERROR;
result = SHA256_Final(digest, &sha->ctx256);
}
@ -339,13 +339,13 @@ int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size)
if (hmac->algorithm == MZ_HASH_SHA1)
{
if (digest_size != MZ_HASH_SHA1_SIZE)
if (digest_size < MZ_HASH_SHA1_SIZE)
return MZ_BUF_ERROR;
result = HMAC_Final(&hmac->ctx, digest, (uint32_t *)digest_size);
}
else
{
if (digest_size != MZ_HASH_SHA256_SIZE)
if (digest_size < MZ_HASH_SHA256_SIZE)
return MZ_BUF_ERROR;
result = HMAC_Final(&hmac->ctx, digest, (uint32_t *)&digest_size);
}

View file

@ -107,7 +107,7 @@ int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size)
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
int32_t result = 0;
if (sha == NULL || buf == NULL)
if (sha == NULL || buf == NULL || sha->hash == 0)
return MZ_PARAM_ERROR;
result = CryptHashData(sha->hash, buf, size, 0);
if (!result)
@ -124,10 +124,10 @@ int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size)
int32_t result = 0;
int32_t expected_size = 0;
if (sha == NULL || digest == NULL)
if (sha == NULL || digest == NULL || sha->hash == 0)
return MZ_PARAM_ERROR;
result = CryptGetHashParam(sha->hash, HP_HASHVAL, NULL, &expected_size, 0);
if (expected_size != digest_size)
if (expected_size > digest_size)
return MZ_BUF_ERROR;
if (!result)
return MZ_HASH_ERROR;
@ -436,7 +436,7 @@ int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size)
if (hmac == NULL || digest == NULL || hmac->hash == 0)
return MZ_PARAM_ERROR;
result = CryptGetHashParam(hmac->hash, HP_HASHVAL, NULL, &expected_size, 0);
if (expected_size != digest_size)
if (expected_size > digest_size)
return MZ_BUF_ERROR;
if (!result)
return MZ_HASH_ERROR;
@ -477,7 +477,9 @@ int32_t mz_crypt_hmac_set_key(void *handle, const void *key, int32_t key_length)
hmac->info.HashAlgid = alg_id;
result = CryptAcquireContext(&hmac->provider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
result = CryptAcquireContext(&hmac->provider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
if (!result)
{
hmac->error = GetLastError();
@ -679,9 +681,10 @@ int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, const char *cert_p
if (ts_context != NULL)
CryptMemFree(ts_context);
#endif
if (result)
#endif
result = CryptSignMessage(&sign_params, FALSE, 1, messages, messages_sizes,
NULL, signature_size);
@ -783,17 +786,18 @@ int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *si
#endif
}
if ((crypt_msg != NULL) && (result) && (decoded_size == signature_size))
if ((crypt_msg != NULL) && (result) && (decoded_size == message_size))
{
if (memcmp(decoded, signature, signature_size) == 0)
// Verify cms message with our stored message
if (memcmp(decoded, message, message_size) == 0)
err = MZ_OK;
}
if (decoded != NULL)
MZ_FREE(decoded);
if (crypt_msg != NULL)
CryptMsgClose(crypt_msg);
if (decoded != NULL)
MZ_FREE(decoded);
return err;
}

View file

@ -91,10 +91,12 @@ int32_t mz_stream_crc32_write(void *stream, const void *buf, int32_t size)
{
mz_stream_crc32 *crc32x = (mz_stream_crc32 *)stream;
int32_t written = 0;
crc32x->value = crc32x->update(crc32x->value, buf, size);
written = mz_stream_write(crc32x->stream.base, buf, size);
if (written > 0)
{
crc32x->value = crc32x->update(crc32x->value, buf, written);
crc32x->total_out += written;
}
return written;
}

View file

@ -104,9 +104,11 @@ int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode)
path_wide = mz_os_unicode_string_create(path);
#ifdef MZ_WINRT_API
win32->handle = CreateFile2W(path_wide, desired_access, share_mode, creation_disposition, NULL);
win32->handle = CreateFile2W(path_wide, desired_access, share_mode,
creation_disposition, NULL);
#else
win32->handle = CreateFileW(path_wide, desired_access, share_mode, NULL, creation_disposition, flags_attribs, NULL);
win32->handle = CreateFileW(path_wide, desired_access, share_mode, NULL,
creation_disposition, flags_attribs, NULL);
#endif
mz_os_unicode_string_delete(&path_wide);
@ -167,7 +169,8 @@ int32_t mz_stream_os_write(void *stream, const void *buf, int32_t size)
return written;
}
static int32_t mz_stream_os_seekinternal(HANDLE handle, LARGE_INTEGER large_pos, LARGE_INTEGER *new_pos, uint32_t move_method)
static int32_t mz_stream_os_seekinternal(HANDLE handle, LARGE_INTEGER large_pos,
LARGE_INTEGER *new_pos, uint32_t move_method)
{
#ifdef MZ_WINRT_API
return SetFilePointerEx(handle, pos, newPos, dwMoveMethod);

View file

@ -91,7 +91,8 @@ static int32_t mz_stream_split_open_disk(void *stream, int32_t number_disk)
{
if (split->path_disk[i] != '.')
continue;
snprintf(&split->path_disk[i], split->path_disk_size - (uint32_t)i, ".z%02"PRId32, number_disk + 1);
snprintf(&split->path_disk[i], split->path_disk_size - (uint32_t)i,
".z%02"PRId32, number_disk + 1);
break;
}
}

View file

@ -55,7 +55,7 @@ typedef struct mz_stream_wzaes_s {
int32_t mode;
int32_t error;
int16_t initialized;
uint8_t buffer[INT16_MAX];
uint8_t buffer[UINT16_MAX];
int64_t total_in;
int64_t max_total_in;
int64_t total_out;
@ -299,8 +299,16 @@ static int32_t mz_stream_wzaes_encrypt_data(void *stream, uint8_t *buf, int32_t
int32_t mz_stream_wzaes_read(void *stream, void *buf, int32_t size)
{
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
int64_t max_total_in = 0;
int32_t bytes_to_read = size;
int32_t read = 0;
read = mz_stream_read(wzaes->stream.base, buf, size);
max_total_in = wzaes->max_total_in - MZ_AES_FOOTER_SIZE;
if (bytes_to_read + wzaes->total_in > max_total_in)
bytes_to_read = (int32_t)(max_total_in - wzaes->total_in);
read = mz_stream_read(wzaes->stream.base, buf, bytes_to_read);
if (read > 0)
{
mz_crypt_hmac_update(wzaes->hmac, (uint8_t *)buf, read);

View file

@ -98,7 +98,8 @@ int32_t mz_stream_zlib_open(void *stream, const char *path, int32_t mode)
zlib->zstream.next_out = zlib->buffer;
zlib->zstream.avail_out = sizeof(zlib->buffer);
zlib->error = deflateInit2(&zlib->zstream, (int8_t)zlib->level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
zlib->error = deflateInit2(&zlib->zstream, (int8_t)zlib->level, Z_DEFLATED,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
#endif
}
else if (mode & MZ_OPEN_MODE_READ)

View file

@ -1014,7 +1014,8 @@ static int32_t mz_zip_entry_write_header(void *stream, uint8_t local, mz_zip_fil
if (file_info->extrafield_size > 0)
{
mz_stream_mem_create(&file_extra_stream);
mz_stream_mem_set_buffer(file_extra_stream, (void *)file_info->extrafield, file_info->extrafield_size);
mz_stream_mem_set_buffer(file_extra_stream, (void *)file_info->extrafield,
file_info->extrafield_size);
do
{
@ -1667,6 +1668,18 @@ int32_t mz_zip_entry_get_local_info(void *handle, mz_zip_file **local_file_info)
return MZ_OK;
}
int32_t mz_zip_entry_set_extrafield(void *handle, const uint8_t *extrafield, uint16_t extrafield_size)
{
mz_zip *zip = (mz_zip *)handle;
if (zip == NULL || mz_zip_entry_is_open(handle) != MZ_OK)
return MZ_PARAM_ERROR;
zip->file_info.extrafield = extrafield;
zip->file_info.extrafield_size = extrafield_size;
return MZ_OK;
}
int32_t mz_zip_entry_close(void *handle)
{
return mz_zip_entry_close_raw(handle, 0, 0);
@ -1681,12 +1694,11 @@ int32_t mz_zip_entry_close_raw(void *handle, int64_t uncompressed_size, uint32_t
if (zip == NULL || mz_zip_entry_is_open(handle) != MZ_OK)
return MZ_PARAM_ERROR;
mz_stream_close(zip->compress_stream);
mz_stream_close(zip->crc32_stream);
if (!zip->entry_raw)
crc32 = zip->file_info.crc;
crc32 = mz_stream_crc32_get_value(zip->crc32_stream);
if ((zip->open_mode & MZ_OPEN_MODE_WRITE) == 0)
{
@ -1721,6 +1733,7 @@ int32_t mz_zip_entry_close_raw(void *handle, int64_t uncompressed_size, uint32_t
mz_stream_delete(&zip->crypt_stream);
mz_stream_delete(&zip->compress_stream);
mz_stream_close(zip->crc32_stream);
mz_stream_crc32_delete(&zip->crc32_stream);
if (zip->open_mode & MZ_OPEN_MODE_WRITE)

View file

@ -125,6 +125,9 @@ int32_t mz_zip_entry_get_info(void *handle, mz_zip_file **file_info);
int32_t mz_zip_entry_get_local_info(void *handle, mz_zip_file **local_file_info);
// Get local info about the current file, only valid while current entry is being read
int32_t mz_zip_entry_set_extrafield(void *handle, const uint8_t *extrafield, uint16_t extrafield_size);
// Sets or updates the extra field for the entry to be used before writing cd
int32_t mz_zip_entry_close_raw(void *handle, int64_t uncompressed_size, uint32_t crc32);
// Close the current file in the zip file where raw is compressed data

View file

@ -42,7 +42,9 @@ typedef struct mz_zip_reader_s {
void *buffered_stream;
void *split_stream;
void *mem_stream;
void *sha256;
void *hash;
uint16_t hash_algorithm;
uint16_t hash_digest_size;
mz_zip_file *file_info;
const char *pattern;
uint8_t pattern_ignore_case;
@ -271,7 +273,9 @@ int32_t mz_zip_reader_unzip_cd(void *handle)
if (mz_stream_mem_is_open(cd_mem_stream) != MZ_OK)
mz_stream_mem_open(cd_mem_stream, NULL, MZ_OPEN_MODE_CREATE);
err = mz_stream_copy_stream(cd_mem_stream, NULL, handle, mz_zip_reader_entry_read, (int32_t)cd_info->uncompressed_size);
err = mz_stream_copy_stream(cd_mem_stream, NULL, handle, mz_zip_reader_entry_read,
(int32_t)cd_info->uncompressed_size);
if (err == MZ_OK)
{
mz_zip_set_cd_stream(reader->zip_handle, 0, cd_mem_stream);
@ -373,31 +377,43 @@ int32_t mz_zip_reader_entry_open(void *handle)
return MZ_PARAM_ERROR;
// If the entry isn't open for reading, open it
if (mz_zip_entry_is_open(reader->zip_handle) != MZ_OK)
if (mz_zip_entry_is_open(reader->zip_handle) == MZ_OK)
return MZ_OK;
password = reader->password;
// Check if we need a password and ask for it if we need to
if ((reader->file_info->flag & MZ_ZIP_FLAG_ENCRYPTED) && (password == NULL) &&
(reader->password_cb != NULL))
{
password = reader->password;
reader->password_cb(handle, reader->password_userdata, reader->file_info,
password_buf, sizeof(password_buf));
// Check if we need a password and ask for it if we need to
if ((reader->file_info->flag & MZ_ZIP_FLAG_ENCRYPTED) && (password == NULL) &&
(reader->password_cb != NULL))
{
reader->password_cb(handle, reader->password_userdata, reader->file_info, password_buf, sizeof(password_buf));
password = password_buf;
}
password = password_buf;
}
err = mz_zip_entry_read_open(reader->zip_handle, reader->raw, password);
err = mz_zip_entry_read_open(reader->zip_handle, reader->raw, password);
#ifndef MZ_ZIP_NO_ENCRYPTION
if (err != MZ_OK)
return err;
if (mz_zip_reader_entry_get_best_hash(handle, &reader->hash_algorithm, &reader->hash_digest_size) == MZ_OK)
{
mz_crypt_sha_create(&reader->hash);
if (reader->hash_algorithm == MZ_HASH_SHA1)
mz_crypt_sha_set_algorithm(reader->hash, MZ_HASH_SHA1);
else if (reader->hash_algorithm == MZ_HASH_SHA256)
mz_crypt_sha_set_algorithm(reader->hash, MZ_HASH_SHA256);
else
err = MZ_SUPPORT_ERROR;
if (err == MZ_OK)
{
mz_crypt_sha_create(&reader->sha256);
mz_crypt_sha_set_algorithm(reader->sha256, MZ_HASH_SHA256);
mz_crypt_sha_begin(reader->hash);
#ifndef MZ_ZIP_NO_SIGNING
if (mz_zip_reader_entry_has_sign(handle) == MZ_OK)
err = mz_zip_reader_entry_sign_verify(handle);
#endif
}
if ((err == MZ_OK) && (mz_zip_reader_entry_has_sign(handle) == MZ_OK))
err = mz_zip_reader_entry_sign_verify(handle);
#endif
}
#endif
return err;
}
@ -409,19 +425,23 @@ int32_t mz_zip_reader_entry_close(void *handle)
int32_t err_close = MZ_OK;
#ifndef MZ_ZIP_NO_ENCRYPTION
int32_t err_hash = MZ_OK;
uint8_t computed_sha1[MZ_HASH_SHA1_SIZE];
uint8_t expected_sha1[MZ_HASH_SHA1_SIZE];
uint8_t computed_hash[MZ_HASH_MAX_SIZE];
uint8_t expected_hash[MZ_HASH_MAX_SIZE];
mz_crypt_sha_end(reader->sha256, computed_sha1, sizeof(computed_sha1));
mz_crypt_sha_delete(&reader->sha256);
err_hash = mz_zip_reader_entry_get_hash(handle, MZ_HASH_SHA1, expected_sha1, sizeof(expected_sha1));
if (err_hash == MZ_OK)
if (reader->hash != NULL)
{
// Verify expected hash against computed hash
if (memcmp(computed_sha1, expected_sha1, MZ_HASH_SHA1_SIZE) != 0)
err = MZ_CRC_ERROR;
mz_crypt_sha_end(reader->hash, computed_hash, sizeof(computed_hash));
mz_crypt_sha_delete(&reader->hash);
err_hash = mz_zip_reader_entry_get_hash(handle, reader->hash_algorithm, expected_hash,
reader->hash_digest_size);
if (err_hash == MZ_OK)
{
// Verify expected hash against computed hash
if (memcmp(computed_hash, expected_hash, reader->hash_digest_size) != 0)
err = MZ_CRC_ERROR;
}
}
#endif
@ -437,8 +457,8 @@ int32_t mz_zip_reader_entry_read(void *handle, void *buf, int32_t len)
int32_t read = 0;
read = mz_zip_entry_read(reader->zip_handle, buf, len);
#ifndef MZ_ZIP_NO_ENCRYPTION
if (read > 0)
mz_crypt_sha_update(reader->sha256, buf, read);
if ((read > 0) && (reader->hash != NULL))
mz_crypt_sha_update(reader->hash, buf, read);
#endif
return read;
}
@ -451,7 +471,8 @@ int32_t mz_zip_reader_entry_has_sign(void *handle)
mz_stream_mem_create(&file_extra_stream);
mz_stream_mem_set_buffer(file_extra_stream, (void *)reader->file_info->extrafield, reader->file_info->extrafield_size);
mz_stream_mem_set_buffer(file_extra_stream, (void *)reader->file_info->extrafield,
reader->file_info->extrafield_size);
err = mz_zip_extrafield_find(file_extra_stream, MZ_ZIP_EXTENSION_SIGN, NULL);
@ -468,13 +489,14 @@ int32_t mz_zip_reader_entry_sign_verify(void *handle)
int32_t err = MZ_OK;
uint8_t *signature = NULL;
uint16_t signature_size = 0;
uint8_t sha256[MZ_HASH_SHA256_SIZE];
uint8_t hash[MZ_HASH_MAX_SIZE];
if (reader == NULL || mz_zip_entry_is_open(reader->zip_handle) != MZ_OK)
return MZ_PARAM_ERROR;
mz_stream_mem_create(&file_extra_stream);
mz_stream_mem_set_buffer(file_extra_stream, (void *)reader->file_info->extrafield, reader->file_info->extrafield_size);
mz_stream_mem_set_buffer(file_extra_stream, (void *)reader->file_info->extrafield,
reader->file_info->extrafield_size);
err = mz_zip_extrafield_find(file_extra_stream, MZ_ZIP_EXTENSION_SIGN, &signature_size);
if ((err == MZ_OK) && (signature_size > 0))
@ -487,12 +509,15 @@ int32_t mz_zip_reader_entry_sign_verify(void *handle)
mz_stream_mem_delete(&file_extra_stream);
if (err == MZ_OK)
err = mz_zip_reader_entry_get_hash(handle, MZ_HASH_SHA256, sha256, sizeof(sha256));
{
// Get most secure hash to verify signature against
err = mz_zip_reader_entry_get_hash(handle, reader->hash_algorithm, hash, reader->hash_digest_size);
}
if (err == MZ_OK)
{
// Verify the pkcs signature
err = mz_crypt_sign_verify(sha256, sizeof(sha256), signature, signature_size);
err = mz_crypt_sign_verify(hash, reader->hash_digest_size, signature, signature_size);
}
if (signature != NULL)
@ -507,11 +532,13 @@ int32_t mz_zip_reader_entry_get_hash(void *handle, uint16_t algorithm, uint8_t *
mz_zip_reader *reader = (mz_zip_reader *)handle;
void *file_extra_stream = NULL;
int32_t err = MZ_OK;
int32_t return_err = MZ_EXIST_ERROR;
uint16_t cur_algorithm = 0;
uint16_t cur_digest_size = 0;
mz_stream_mem_create(&file_extra_stream);
mz_stream_mem_set_buffer(file_extra_stream, (void *)reader->file_info->extrafield, reader->file_info->extrafield_size);
mz_stream_mem_set_buffer(file_extra_stream, (void *)reader->file_info->extrafield,
reader->file_info->extrafield_size);
do
{
@ -522,23 +549,82 @@ int32_t mz_zip_reader_entry_get_hash(void *handle, uint16_t algorithm, uint8_t *
err = mz_stream_read_uint16(file_extra_stream, &cur_algorithm);
if (err == MZ_OK)
err = mz_stream_read_uint16(file_extra_stream, &cur_digest_size);
if ((cur_algorithm == algorithm) && (cur_digest_size == digest_size))
if ((cur_algorithm == algorithm) && (cur_digest_size <= digest_size) &&
(cur_digest_size <= MZ_HASH_MAX_SIZE))
{
// Read hash digest into file info
// Read hash digest
if (mz_stream_read(file_extra_stream, digest, digest_size) != cur_digest_size)
err = MZ_FORMAT_ERROR;
else
return_err = MZ_OK;
break;
}
else
{
mz_stream_seek(file_extra_stream, cur_digest_size, SEEK_CUR);
err = mz_stream_seek(file_extra_stream, cur_digest_size, SEEK_CUR);
}
break;
}
while (err == MZ_OK);
mz_stream_mem_delete(&file_extra_stream);
return err;
return return_err;
}
int32_t mz_zip_reader_entry_get_best_hash(void *handle, uint16_t *algorithm, uint16_t *digest_size)
{
mz_zip_reader *reader = (mz_zip_reader *)handle;
void *file_extra_stream = NULL;
int32_t err = MZ_OK;
int32_t return_err = MZ_EXIST_ERROR;
uint16_t last_algorithm = 0;
uint16_t cur_algorithm = 0;
uint16_t cur_digest_size = 0;
if (reader == NULL || algorithm == NULL)
return MZ_PARAM_ERROR;
mz_stream_mem_create(&file_extra_stream);
mz_stream_mem_set_buffer(file_extra_stream, (void *)reader->file_info->extrafield,
reader->file_info->extrafield_size);
do
{
err = mz_zip_extrafield_find(file_extra_stream, MZ_ZIP_EXTENSION_HASH, NULL);
if (err != MZ_OK)
break;
err = mz_stream_read_uint16(file_extra_stream, &cur_algorithm);
if (err == MZ_OK)
err = mz_stream_read_uint16(file_extra_stream, &cur_digest_size);
if ((cur_algorithm > last_algorithm) && (cur_digest_size <= MZ_HASH_MAX_SIZE))
{
last_algorithm = cur_algorithm;
if (algorithm != NULL)
*algorithm = cur_algorithm;
if (digest_size != NULL)
*digest_size = cur_digest_size;
return_err = MZ_OK;
}
err = mz_stream_seek(file_extra_stream, cur_digest_size, SEEK_CUR);
}
while (err == MZ_OK);
mz_stream_mem_delete(&file_extra_stream);
if (return_err != MZ_OK)
{
if (digest_size != NULL)
*digest_size = 0;
if (algorithm != NULL)
*algorithm = 0;
}
return return_err;
}
int32_t mz_zip_reader_entry_get_info(void *handle, mz_zip_file **file_info)
@ -723,8 +809,9 @@ int32_t mz_zip_reader_entry_save_file(void *handle, const char *path)
if (err == MZ_OK)
{
// Set file attributes for the correct system
err_attrib = mz_zip_attrib_convert(MZ_HOST_SYSTEM(reader->file_info->version_madeby), reader->file_info->external_fa,
MZ_VERSION_MADEBY_HOST_SYSTEM, &target_attrib);
err_attrib = mz_zip_attrib_convert(MZ_HOST_SYSTEM(reader->file_info->version_madeby),
reader->file_info->external_fa, MZ_VERSION_MADEBY_HOST_SYSTEM, &target_attrib);
if (err_attrib == MZ_OK)
mz_os_set_file_attribs(path, target_attrib);
}
@ -1214,19 +1301,21 @@ int32_t mz_zip_writer_entry_open(void *handle, mz_zip_file *file_info)
if ((writer->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED) && (password == NULL) &&
(writer->password_cb != NULL))
{
writer->password_cb(handle, writer->password_userdata, &writer->file_info, password_buf, sizeof(password_buf));
writer->password_cb(handle, writer->password_userdata, &writer->file_info,
password_buf, sizeof(password_buf));
password = password_buf;
}
#ifndef MZ_ZIP_NO_ENCRYPTION
// Start calculating sha1
// Start calculating sha256
mz_crypt_sha_create(&writer->sha256);
mz_crypt_sha_set_algorithm(writer->sha256, MZ_HASH_SHA256);
mz_crypt_sha_begin(writer->sha256);
#endif
// Open entry in zip
err = mz_zip_entry_write_open(writer->zip_handle, &writer->file_info, writer->compress_level, writer->raw, password);
err = mz_zip_entry_write_open(writer->zip_handle, &writer->file_info, writer->compress_level,
writer->raw, password);
return err;
}
@ -1236,7 +1325,7 @@ int32_t mz_zip_writer_entry_close(void *handle)
mz_zip_writer *writer = (mz_zip_writer *)handle;
int32_t err = MZ_OK;
#ifndef MZ_ZIP_NO_ENCRYPTION
mz_zip_file *file_info = NULL;
const uint8_t *extrafield = NULL;
int32_t extrafield_size = 0;
int32_t field_length_hash = 0;
uint8_t sha256[MZ_HASH_SHA256_SIZE];
@ -1244,15 +1333,15 @@ int32_t mz_zip_writer_entry_close(void *handle)
mz_crypt_sha_end(writer->sha256, sha256, sizeof(sha256));
mz_crypt_sha_delete(&writer->sha256);
// Copy extrafield so we can append our own fields before close
mz_stream_mem_create(&writer->file_extra_stream);
mz_stream_mem_open(writer->file_extra_stream, NULL, MZ_OPEN_MODE_CREATE);
if ((writer->file_info.extrafield != NULL) && (writer->file_info.extrafield_size > 0))
mz_stream_mem_write(writer->file_extra_stream, writer->file_info.extrafield, writer->file_info.extrafield_size);
mz_stream_mem_write(writer->file_extra_stream, writer->file_info.extrafield,
writer->file_info.extrafield_size);
// Write sha1 hash to extrafield
// Write sha256 hash to extrafield
field_length_hash = 4 + MZ_HASH_SHA256_SIZE;
err = mz_zip_extrafield_write(writer->file_extra_stream, MZ_ZIP_EXTENSION_HASH, field_length_hash);
if (err == MZ_OK)
@ -1271,15 +1360,15 @@ int32_t mz_zip_writer_entry_close(void *handle)
#endif
// Update extra field for central directory after adding extra fields
mz_zip_entry_get_info(writer->zip_handle, &file_info);
mz_stream_mem_get_buffer(writer->file_extra_stream, (const void **)&file_info->extrafield);
mz_stream_mem_get_buffer(writer->file_extra_stream, (const void **)&extrafield);
mz_stream_mem_get_buffer_length(writer->file_extra_stream, &extrafield_size);
file_info->extrafield_size = (uint16_t)extrafield_size;
mz_zip_entry_set_extrafield(writer->zip_handle, extrafield, (uint16_t)extrafield_size);
#endif
if (writer->raw)
err = mz_zip_entry_close_raw(writer->zip_handle, writer->file_info.uncompressed_size, writer->file_info.crc);
err = mz_zip_entry_close_raw(writer->zip_handle, writer->file_info.uncompressed_size,
writer->file_info.crc);
else
err = mz_zip_entry_close(writer->zip_handle);
@ -1299,7 +1388,8 @@ int32_t mz_zip_writer_entry_write(void *handle, const void *buf, int32_t len)
}
#if !defined(MZ_ZIP_NO_ENCRYPTION) && !defined(MZ_ZIP_NO_SIGNING)
int32_t mz_zip_writer_entry_sign(void *handle, uint8_t *message, int32_t message_size, const char *cert_path, const char *cert_pwd)
int32_t mz_zip_writer_entry_sign(void *handle, uint8_t *message, int32_t message_size,
const char *cert_path, const char *cert_pwd)
{
mz_zip_writer *writer = (mz_zip_writer *)handle;
int32_t err = MZ_OK;
@ -1549,7 +1639,8 @@ int32_t mz_zip_writer_add_file(void *handle, const char *path, const char *filen
return err;
}
int32_t mz_zip_writer_add_path(void *handle, const char *path, const char *root_path, uint8_t include_path, uint8_t recursive)
int32_t mz_zip_writer_add_path(void *handle, const char *path, const char *root_path, uint8_t include_path,
uint8_t recursive)
{
DIR *dir = NULL;
struct dirent *entry = NULL;

View file

@ -81,6 +81,9 @@ int32_t mz_zip_reader_entry_sign_verify(void *handle);
int32_t mz_zip_reader_entry_get_hash(void *handle, uint16_t algorithm, uint8_t *digest, int32_t digest_size);
// Gets a hash algorithm from the entry's extra field
int32_t mz_zip_reader_entry_get_best_hash(void *handle, uint16_t *algorithm, uint16_t *digest_size);
// Gets the most secure hash algorithm from the entry's extra field
int32_t mz_zip_reader_entry_get_info(void *handle, mz_zip_file **file_info);
// Gets the current entry file info