From 3323ea2840fb169ec8eea858c18fe12838feaf35 Mon Sep 17 00:00:00 2001 From: Michihiro NAKAJIMA Date: Sun, 14 Sep 2014 19:23:44 +0900 Subject: [PATCH] Switch passing passphrases from option framework to new APIs for encryption and decryption. --- libarchive/archive_read_support_format_zip.c | 28 ++++++--------- libarchive/archive_write_set_format_zip.c | 36 ++++++------------- ...d_format_zip_traditional_encryption_data.c | 4 +-- .../test/test_read_format_zip_winzip_aes.c | 4 +-- .../test_read_format_zip_winzip_aes_large.c | 4 +-- libarchive/test/test_write_format_zip.c | 36 +++++++++---------- 6 files changed, 46 insertions(+), 66 deletions(-) diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c index 24af61d27..f2ec5f2a9 100644 --- a/libarchive/archive_read_support_format_zip.c +++ b/libarchive/archive_read_support_format_zip.c @@ -177,7 +177,6 @@ struct zip { int init_default_conversion; int process_mac_extensions; - struct archive_string password; char init_decryption; /* Decryption buffer. */ @@ -1574,6 +1573,7 @@ static int init_traditional_PKWARE_decryption(struct archive_read *a) { struct zip *zip = (struct zip *)(a->format->data); + const char *passphrase; const void *p; uint8_t crcchk; int r; @@ -1581,7 +1581,8 @@ init_traditional_PKWARE_decryption(struct archive_read *a) if (zip->tctx_valid) return (ARCHIVE_OK); - if (archive_strlen(&zip->password) == 0) { + passphrase = __archive_read_next_passphrase(a); + if (passphrase == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Passowrd required for this entry"); return (ARCHIVE_FAILED); @@ -1601,8 +1602,8 @@ init_traditional_PKWARE_decryption(struct archive_read *a) /* * Initialize ctx for Traditional PKWARE Decyption. */ - r = trad_enc_init(&zip->tctx, zip->password.s, - archive_strlen(&zip->password), p, ENC_HEADER_SIZE, &crcchk); + r = trad_enc_init(&zip->tctx, passphrase, strlen(passphrase), + p, ENC_HEADER_SIZE, &crcchk); if (crcchk != zip->entry->decdat || r != 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Incorrect passowrd"); @@ -1624,6 +1625,7 @@ static int init_WinZip_AES_decryption(struct archive_read *a) { struct zip *zip = (struct zip *)(a->format->data); + const char *passphrase; const void *p; const uint8_t *pv; size_t key_len, salt_len; @@ -1633,7 +1635,8 @@ init_WinZip_AES_decryption(struct archive_read *a) if (zip->cctx_valid || zip->hctx_valid) return (ARCHIVE_OK); - if (archive_strlen(&zip->password) == 0) { + passphrase = __archive_read_next_passphrase(a); + if (passphrase == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Passowrd required for this entry"); return (ARCHIVE_FAILED); @@ -1650,7 +1653,7 @@ init_WinZip_AES_decryption(struct archive_read *a) goto truncated; memset(derived_key, 0, sizeof(derived_key)); - archive_pbkdf2_sha1(zip->password.s, archive_strlen(&zip->password), + archive_pbkdf2_sha1(passphrase, strlen(passphrase), p, salt_len, 1000, derived_key, key_len * 2 + 2); /* Check password verification value. */ @@ -1822,11 +1825,6 @@ archive_read_format_zip_cleanup(struct archive_read *a) zip_entry = next_zip_entry; } } - if (zip->password.s != NULL) { - /* Clean password characters up. */ - memset(zip->password.s, 0, archive_strlen(&zip->password)); - archive_string_free(&zip->password); - } free(zip->decrypted_buffer); if (zip->cctx_valid) archive_decrypto_aes_ctr_release(&zip->cctx); @@ -1893,12 +1891,6 @@ archive_read_format_zip_options(struct archive_read *a, } else if (strcmp(key, "mac-ext") == 0) { zip->process_mac_extensions = (val != NULL && val[0] != 0); return (ARCHIVE_OK); - } else if (strcmp(key, "password") == 0) { - if (val != NULL) - archive_strcpy(&zip->password, val); - else - archive_string_empty(&zip->password); - return (ARCHIVE_OK); } /* Note: The "warn" return is just to inform the options @@ -2008,6 +2000,7 @@ archive_read_format_zip_streamable_read_header(struct archive_read *a, if (zip->hctx_valid) archive_hmac_sha1_cleanup(&zip->hctx); zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0; + __archive_read_reset_passphrase(a); /* Search ahead for the next local file header. */ __archive_read_consume(a, zip->unconsumed); @@ -2845,6 +2838,7 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a, if (zip->hctx_valid) archive_hmac_sha1_cleanup(&zip->hctx); zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0; + __archive_read_reset_passphrase(a); /* File entries are sorted by the header offset, we should mostly * use __archive_read_consume to advance a read point to avoid redundant diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c index 88688cb7e..e604e1edc 100644 --- a/libarchive/archive_write_set_format_zip.c +++ b/libarchive/archive_write_set_format_zip.c @@ -155,7 +155,6 @@ struct zip { enum compression requested_compression; int init_default_conversion; enum encryption encryption_type; - struct archive_string password; #define ZIP_FLAG_AVOID_ZIP64 1 #define ZIP_FLAG_FORCE_ZIP64 2 @@ -350,16 +349,6 @@ archive_write_zip_options(struct archive_write *a, const char *key, ret = ARCHIVE_FATAL; } return (ret); - } else if (strcmp(key, "password") == 0) { - if (val == NULL || val[0] == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: password option needs its value", - a->format_name); - } else { - archive_strcpy(&zip->password, val); - ret = ARCHIVE_OK; - } - return (ret); } else if (strcmp(key, "zip64") == 0) { /* * Bias decisions about Zip64: force them to be @@ -1327,10 +1316,6 @@ archive_write_zip_free(struct archive_write *a) } free(zip->buf); archive_entry_free(zip->entry); - if (zip->password.s != NULL) { - memset(zip->password.s, 0, archive_strlen(&zip->password)); - archive_string_free(&zip->password); - } if (zip->cctx_valid) archive_encrypto_aes_ctr_release(&zip->cctx); if (zip->hctx_valid) @@ -1522,14 +1507,15 @@ static int init_traditional_pkware_encryption(struct archive_write *a) { struct zip *zip = a->format_data; + const char *passphrase; uint8_t key[TRAD_HEADER_SIZE]; uint8_t key_encrypted[TRAD_HEADER_SIZE]; int ret; - if (zip->password.s == NULL - || archive_strlen(&zip->password) == 0) { + passphrase = __archive_write_get_passphrase(a); + if (passphrase == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Encryption needs password"); + "Encryption needs passphrase"); return ARCHIVE_FAILED; } if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK) { @@ -1537,10 +1523,9 @@ init_traditional_pkware_encryption(struct archive_write *a) "Can't generate random number for encryption"); return ARCHIVE_FATAL; } - trad_enc_init(&zip->tctx, zip->password.s, - archive_strlen(&zip->password)); + trad_enc_init(&zip->tctx, passphrase, strlen(passphrase)); /* Set the last key code which will be used as a check code - * for ferifying password in decryption. */ + * for verifying passphrase in decryption. */ key[TRAD_HEADER_SIZE-1] = zip->trad_chkdat; trad_enc_encrypt_update(&zip->tctx, key, TRAD_HEADER_SIZE, key_encrypted, TRAD_HEADER_SIZE); @@ -1557,15 +1542,16 @@ static int init_winzip_aes_encryption(struct archive_write *a) { struct zip *zip = a->format_data; + const char *passphrase; size_t key_len, salt_len; uint8_t salt[16 + 2]; uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE]; int ret; - if (zip->password.s == NULL - || archive_strlen(&zip->password) == 0) { + passphrase = __archive_write_get_passphrase(a); + if (passphrase == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Encryption needs password"); + "Encryption needs passphrase"); return (ARCHIVE_FAILED); } if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128) { @@ -1581,7 +1567,7 @@ init_winzip_aes_encryption(struct archive_write *a) "Can't generate random number for encryption"); return (ARCHIVE_FATAL); } - archive_pbkdf2_sha1(zip->password.s, archive_strlen(&zip->password), + archive_pbkdf2_sha1(passphrase, strlen(passphrase), salt, salt_len, 1000, derived_key, key_len * 2 + 2); ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len); diff --git a/libarchive/test/test_read_format_zip_traditional_encryption_data.c b/libarchive/test/test_read_format_zip_traditional_encryption_data.c index a0f033b0f..3b9fc1102 100644 --- a/libarchive/test/test_read_format_zip_traditional_encryption_data.c +++ b/libarchive/test/test_read_format_zip_traditional_encryption_data.c @@ -104,9 +104,9 @@ DEFINE_TEST(test_read_format_zip_traditional_encryption_data) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=12345678")); + archive_read_add_passphrase(a, "12345678")); assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); + archive_read_open_filename(a, refname, 10240)); assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); diff --git a/libarchive/test/test_read_format_zip_winzip_aes.c b/libarchive/test/test_read_format_zip_winzip_aes.c index 61e64b643..1cd05c25a 100644 --- a/libarchive/test/test_read_format_zip_winzip_aes.c +++ b/libarchive/test/test_read_format_zip_winzip_aes.c @@ -90,9 +90,9 @@ test_winzip_aes(const char *refname) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password")); + archive_read_add_passphrase(a, "password")); assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); + archive_read_open_filename(a, refname, 10240)); assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); diff --git a/libarchive/test/test_read_format_zip_winzip_aes_large.c b/libarchive/test/test_read_format_zip_winzip_aes_large.c index db7112a40..6cff24840 100644 --- a/libarchive/test/test_read_format_zip_winzip_aes_large.c +++ b/libarchive/test/test_read_format_zip_winzip_aes_large.c @@ -108,9 +108,9 @@ DEFINE_TEST(test_read_format_zip_winzip_aes256_large) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password")); + archive_read_add_passphrase(a, "password")); assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); + archive_read_open_filename(a, refname, 10240)); assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); diff --git a/libarchive/test/test_write_format_zip.c b/libarchive/test/test_write_format_zip.c index 002d18eec..879451d8b 100644 --- a/libarchive/test/test_write_format_zip.c +++ b/libarchive/test/test_write_format_zip.c @@ -688,7 +688,7 @@ DEFINE_TEST(test_write_format_zip_traditional_pkware_encryption) return; } assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:password=password1234")); + archive_write_set_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:experimental")); assertEqualIntA(a, ARCHIVE_OK, @@ -704,7 +704,7 @@ DEFINE_TEST(test_write_format_zip_traditional_pkware_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); verify_contents(a, 1, 1); @@ -713,7 +713,7 @@ DEFINE_TEST(test_write_format_zip_traditional_pkware_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); /* Streaming reader doesn't see mode information from Central Directory. */ verify_contents(a, 0, 1); @@ -722,7 +722,7 @@ DEFINE_TEST(test_write_format_zip_traditional_pkware_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); /* Streaming reader doesn't see mode information from Central Directory. */ verify_contents(a, 0, 0); @@ -732,7 +732,7 @@ DEFINE_TEST(test_write_format_zip_traditional_pkware_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); verify_contents(a, 1, 1); @@ -740,7 +740,7 @@ DEFINE_TEST(test_write_format_zip_traditional_pkware_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); verify_contents(a, 1, 0); @@ -767,7 +767,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes128_encryption) return; } assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:password=password1234")); + archive_write_set_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:experimental")); assertEqualIntA(a, ARCHIVE_OK, @@ -783,7 +783,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes128_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); verify_contents(a, 1, 1); @@ -792,7 +792,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes128_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); /* Streaming reader doesn't see mode information from Central Directory. */ verify_contents(a, 0, 1); @@ -801,7 +801,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes128_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); /* Streaming reader doesn't see mode information from Central Directory. */ verify_contents(a, 0, 0); @@ -811,7 +811,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes128_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); verify_contents(a, 1, 1); @@ -819,7 +819,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes128_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); verify_contents(a, 1, 0); @@ -846,7 +846,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes256_encryption) return; } assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:password=password1234")); + archive_write_set_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:experimental")); assertEqualIntA(a, ARCHIVE_OK, @@ -862,7 +862,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes256_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); verify_contents(a, 1, 1); @@ -871,7 +871,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes256_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); /* Streaming reader doesn't see mode information from Central Directory. */ verify_contents(a, 0, 1); @@ -880,7 +880,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes256_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); /* Streaming reader doesn't see mode information from Central Directory. */ verify_contents(a, 0, 0); @@ -890,7 +890,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes256_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); verify_contents(a, 1, 1); @@ -898,7 +898,7 @@ DEFINE_TEST(test_write_format_zip_winzip_aes256_encryption) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:password=password1234")); + archive_read_add_passphrase(a, "password1234")); assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); verify_contents(a, 1, 0); -- 2.47.2