diff options
Diffstat (limited to 'src/Common/libzip/zip_source_pkware_decode.c')
-rw-r--r-- | src/Common/libzip/zip_source_pkware_decode.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/src/Common/libzip/zip_source_pkware_decode.c b/src/Common/libzip/zip_source_pkware_decode.c index b4c482b3..9c22a069 100644 --- a/src/Common/libzip/zip_source_pkware_decode.c +++ b/src/Common/libzip/zip_source_pkware_decode.c @@ -1,6 +1,6 @@ /* zip_source_pkware_decode.c -- Traditional PKWARE decryption routines - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2024 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <info@libzip.org> @@ -80,9 +80,9 @@ zip_source_pkware_decode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flag static int decrypt_header(zip_source_t *src, struct trad_pkware *ctx) { zip_uint8_t header[ZIP_CRYPTO_PKWARE_HEADERLEN]; - struct zip_stat st; + zip_stat_t st; + zip_dostime_t dostime; zip_int64_t n; - bool ok = false; if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) { zip_error_set_from_source(&ctx->error, src); @@ -96,36 +96,35 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) { _zip_pkware_decrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN); - if (zip_source_stat(src, &st)) { - /* stat failed, skip password validation */ + if (zip_source_stat(src, &st) < 0 || (st.valid & ZIP_STAT_CRC) == 0) { + /* skip password validation */ return 0; } - /* password verification - two ways: - * mtime - InfoZIP way, to avoid computing complete CRC before encrypting data - * CRC - old PKWare way - */ - - if (st.valid & ZIP_STAT_MTIME) { - unsigned short dostime, dosdate; - _zip_u2d_time(st.mtime, &dostime, &dosdate); - if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime >> 8) { - ok = true; + if (zip_source_get_dos_time(src, &dostime) <= 0) { + if ((st.valid & ZIP_STAT_MTIME) == 0) { + /* no date available, skip password validation */ + return 0; } - } - if (st.valid & ZIP_STAT_CRC) { - if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == st.crc >> 24) { - ok = true; + if (_zip_u2d_time(st.mtime, &dostime, &ctx->error) < 0) { + return -1; } } - if (!ok && ((st.valid & (ZIP_STAT_MTIME | ZIP_STAT_CRC)) != 0)) { + /* + password verification - two ways: + - mtime - InfoZIP way, to avoid computing complete CRC before encrypting data + - CRC - old PKWare way + */ + if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime.time >> 8 + || header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == st.crc >> 24) { + return 0; + } + else { zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0); return -1; } - - return 0; } |