mirror of
https://github.com/zlib-ng/minizip-ng
synced 2026-08-25 14:26:08 -04:00
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:
parent
2ed269e000
commit
915c513abe
14 changed files with 220 additions and 93 deletions
|
|
@ -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
1
mz.h
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
21
mz_zip.c
21
mz_zip.c
|
|
@ -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)
|
||||
|
|
|
|||
3
mz_zip.h
3
mz_zip.h
|
|
@ -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
|
||||
|
||||
|
|
|
|||
209
mz_zip_rw.c
209
mz_zip_rw.c
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue