1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-13 03:48:26 -06:00

Windows: update libzip to version 1.2.0

This commit is contained in:
Mounir IDRASSI
2017-04-26 00:10:55 +02:00
parent 9270952b3d
commit d081d6143e
44 changed files with 795 additions and 319 deletions

View File

@@ -44,6 +44,7 @@
static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);
void
@@ -66,32 +67,61 @@ zip_cdir_t *
_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error)
{
zip_cdir_t *cd;
zip_uint64_t i;
if ((cd=(zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (nentry == 0)
cd->entry = NULL;
else if ((nentry > SIZE_MAX/sizeof(*(cd->entry))) || (cd->entry=(zip_entry_t *)malloc(sizeof(*(cd->entry))*(size_t)nentry)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(cd);
cd->entry = NULL;
cd->nentry = cd->nentry_alloc = 0;
cd->size = cd->offset = 0;
cd->comment = NULL;
cd->is_zip64 = false;
if (!_zip_cdir_grow(cd, nentry, error)) {
_zip_cdir_free(cd);
return NULL;
}
for (i=0; i<nentry; i++)
_zip_entry_init(cd->entry+i);
cd->nentry = cd->nentry_alloc = nentry;
cd->size = cd->offset = 0;
cd->comment = NULL;
return cd;
}
bool
_zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error)
{
zip_uint64_t i, new_alloc;
zip_entry_t *new_entry;
if (additional_entries == 0) {
return true;
}
new_alloc = cd->nentry_alloc + additional_entries;
if (new_alloc < additional_entries || new_alloc > SIZE_MAX/sizeof(*(cd->entry))) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return false;
}
if ((new_entry = (zip_entry_t *)realloc(cd->entry, sizeof(*(cd->entry))*(size_t)new_alloc)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return false;
}
cd->entry = new_entry;
for (i = cd->nentry; i < new_alloc; i++) {
_zip_entry_init(cd->entry+i);
}
cd->nentry = cd->nentry_alloc = new_alloc;
return true;
}
zip_int64_t
_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
{
@@ -222,6 +252,13 @@ _zip_dirent_finalize(zip_dirent_t *zde)
_zip_string_free(zde->comment);
zde->comment = NULL;
}
if (!zde->cloned || zde->changed & ZIP_DIRENT_PASSWORD) {
if (zde->password) {
_zip_crypto_clear(zde->password, strlen(zde->password));
}
free(zde->password);
zde->password = NULL;
}
}
@@ -243,6 +280,7 @@ _zip_dirent_init(zip_dirent_t *de)
de->local_extra_fields_read = 0;
de->cloned = 0;
de->crc_valid = true;
de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8);
de->version_needed = 20; /* 2.0 */
de->bitflags = 0;
@@ -258,6 +296,8 @@ _zip_dirent_init(zip_dirent_t *de)
de->int_attrib = 0;
de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
de->offset = 0;
de->encryption_method = ZIP_EM_NONE;
de->password = NULL;
}
@@ -372,6 +412,19 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1;
}
if (zde->bitflags & ZIP_GPBF_ENCRYPTED) {
if (zde->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
/* TODO */
zde->encryption_method = ZIP_EM_UNKNOWN;
}
else {
zde->encryption_method = ZIP_EM_TRAD_PKWARE;
}
}
else {
zde->encryption_method = ZIP_EM_NONE;
}
zde->filename = NULL;
zde->extra_fields = NULL;
zde->comment = NULL;
@@ -524,6 +577,13 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1;
}
if (!_zip_dirent_process_winzip_aes(zde, error)) {
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
return (zip_int64_t)(size + variable_size);
@@ -566,6 +626,90 @@ _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string
}
static bool
_zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error)
{
zip_uint16_t ef_len;
zip_buffer_t *buffer;
const zip_uint8_t *ef;
bool crc_valid;
zip_uint16_t enc_method;
if (de->comp_method != ZIP_CM_WINZIP_AES) {
return true;
}
ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL);
if (ef == NULL || ef_len < 7) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return false;
}
if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return false;
}
/* version */
crc_valid = true;
switch (_zip_buffer_get_16(buffer)) {
case 1:
break;
case 2:
if (de->uncomp_size < 20 /* TODO: constant */) {
crc_valid = false;
}
break;
default:
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer);
return false;
}
/* vendor */
if (memcmp(_zip_buffer_get(buffer, 2), "AE", 2) != 0) {
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer);
return false;
}
/* mode */
switch (_zip_buffer_get_8(buffer)) {
case 1:
enc_method = ZIP_EM_AES_128;
break;
case 2:
enc_method = ZIP_EM_AES_192;
break;
case 3:
enc_method = ZIP_EM_AES_256;
break;
default:
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer);
return false;
}
if (ef_len != 7) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(buffer);
return false;
}
de->crc_valid = crc_valid;
de->encryption_method = enc_method;
de->comp_method = _zip_buffer_get_16(buffer);
_zip_buffer_free(buffer);
return true;
}
zip_int32_t
_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error)
{
@@ -621,6 +765,7 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
zip_uint32_t ef_total_size;
bool is_zip64;
bool is_really_zip64;
bool is_winzip_aes;
zip_uint8_t buf[CDENTRYSIZE];
zip_buffer_t *buffer;
@@ -651,8 +796,16 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
}
}
if (de->encryption_method == ZIP_EM_NONE) {
de->bitflags &= ~ZIP_GPBF_ENCRYPTED;
}
else {
de->bitflags |= ZIP_GPBF_ENCRYPTED;
}
is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
is_zip64 = (flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64) || is_really_zip64;
is_winzip_aes = de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256;
if (is_zip64) {
zip_uint8_t ef_zip64[EFZIP64SIZE];
@@ -696,6 +849,35 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
ef = ef64;
}
if (is_winzip_aes) {
zip_uint8_t data[EF_WINZIP_AES_SIZE];
zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data));
zip_extra_field_t *ef_winzip;
if (ef_buffer == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
_zip_ef_free(ef);
return -1;
}
_zip_buffer_put_16(ef_buffer, 2);
_zip_buffer_put(ef_buffer, "AE", 2);
_zip_buffer_put_8(ef_buffer, (de->encryption_method & 0xff));
_zip_buffer_put_16(ef_buffer, (zip_uint16_t)de->comp_method);
if (!_zip_buffer_ok(ef_buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(ef_buffer);
_zip_ef_free(ef);
return -1;
}
ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data, ZIP_EF_BOTH);
_zip_buffer_free(ef_buffer);
ef_winzip->next = ef;
ef = ef_winzip;
}
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
_zip_ef_free(ef);
@@ -709,13 +891,23 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
}
_zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
_zip_buffer_put_16(buffer, de->bitflags&0xfff9); /* clear compression method specific flags */
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
if (is_winzip_aes) {
_zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
}
else {
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
}
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
_zip_buffer_put_16(buffer, dostime);
_zip_buffer_put_16(buffer, dosdate);
_zip_buffer_put_32(buffer, de->crc);
if (is_winzip_aes && de->uncomp_size < 20) {
_zip_buffer_put_32(buffer, 0);
}
else {
_zip_buffer_put_32(buffer, de->crc);
}
if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
/* In local headers, if a ZIP64 EF is written, it MUST contain