]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Switch passing passphrases from option framework to new APIs for
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sun, 14 Sep 2014 10:23:44 +0000 (19:23 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sun, 14 Sep 2014 10:23:44 +0000 (19:23 +0900)
encryption and decryption.

libarchive/archive_read_support_format_zip.c
libarchive/archive_write_set_format_zip.c
libarchive/test/test_read_format_zip_traditional_encryption_data.c
libarchive/test/test_read_format_zip_winzip_aes.c
libarchive/test/test_read_format_zip_winzip_aes_large.c
libarchive/test/test_write_format_zip.c

index 24af61d2779001b5d78e743b4957573815dee62c..f2ec5f2a918f0b0d76f836e66562df8de3c0ecb2 100644 (file)
@@ -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
index 88688cb7e7d3af0194062ee3f1c89a181f6afb9c..e604e1edceb7d19745065d266d0348d806213360 100644 (file)
@@ -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);
index a0f033b0f7e7b2736a76e789721cf02edc9d7fb4..3b9fc11024b5144a5cfe4c6e382d47615cac39de 100644 (file)
@@ -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));
index 61e64b643c66e613ec12e78d99c4172f3096e79c..1cd05c25a7452e1b23e819dfbe502c6fd9064869 100644 (file)
@@ -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));
index db7112a4022245a3627ca59d5b24239fd5cb5c68..6cff248400cc82194117437813173d33ef4e92cd 100644 (file)
@@ -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));
index 002d18eec493fa7b6a39d7bd2c7d0f1b120b17fc..879451d8bed0a21252f11b67316a74f5da3ec253 100644 (file)
@@ -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);