@@ -273,6 +273,8 @@ pub struct FileOptions<'k, T: FileOptionExtension> {
273
273
pub ( crate ) alignment : u16 ,
274
274
#[ cfg( feature = "deflate-zopfli" ) ]
275
275
pub ( super ) zopfli_buffer_size : Option < usize > ,
276
+ #[ cfg( feature = "aes-crypto" ) ]
277
+ pub ( crate ) aes_mode : Option < ( AesMode , AesVendorVersion , CompressionMethod ) > ,
276
278
}
277
279
/// Simple File Options. Can be copied and good for simple writing zip files
278
280
pub type SimpleFileOptions = FileOptions < ' static , ( ) > ;
@@ -566,6 +568,8 @@ impl<T: FileOptionExtension> Default for FileOptions<'_, T> {
566
568
alignment : 1 ,
567
569
#[ cfg( feature = "deflate-zopfli" ) ]
568
570
zopfli_buffer_size : Some ( 1 << 15 ) ,
571
+ #[ cfg( feature = "aes-crypto" ) ]
572
+ aes_mode : None ,
569
573
}
570
574
}
571
575
}
@@ -932,9 +936,25 @@ impl<W: Write + Seek> ZipWriter<W> {
932
936
0x9901 ,
933
937
aes_dummy_extra_data,
934
938
) ?;
939
+ } else if let Some ( ( mode, vendor, underlying) ) = options. aes_mode {
940
+ // For raw copies of AES entries, write the correct AES extra data immediately
941
+ let mut body = Vec :: with_capacity ( 7 ) ;
942
+ body. write_u16_le ( vendor as u16 ) ?; // vendor version (1 or 2)
943
+ body. extend_from_slice ( b"AE" ) ; // vendor id
944
+ body. push ( mode as u8 ) ; // strength
945
+ body. write_u16_le ( underlying. serialize_to_u16 ( ) ) ?; // real compression method
946
+ aes_extra_data_start = extra_data. len ( ) as u64 ;
947
+ ExtendedFileOptions :: add_extra_data_unchecked (
948
+ & mut extra_data,
949
+ 0x9901 ,
950
+ body. into_boxed_slice ( ) ,
951
+ ) ?;
935
952
}
936
953
937
954
let ( compression_method, aes_mode) = match options. encrypt_with {
955
+ // Preserve AES method for raw copies without needing a password
956
+ #[ cfg( feature = "aes-crypto" ) ]
957
+ None if options. aes_mode . is_some ( ) => ( CompressionMethod :: Aes , options. aes_mode ) ,
938
958
#[ cfg( feature = "aes-crypto" ) ]
939
959
Some ( EncryptWith :: Aes { mode, .. } ) => (
940
960
CompressionMethod :: Aes ,
@@ -2317,6 +2337,8 @@ mod test {
2317
2337
alignment : 1 ,
2318
2338
#[ cfg( feature = "deflate-zopfli" ) ]
2319
2339
zopfli_buffer_size : None ,
2340
+ #[ cfg( feature = "aes-crypto" ) ]
2341
+ aes_mode : None ,
2320
2342
} ;
2321
2343
writer. start_file ( "mimetype" , options) . unwrap ( ) ;
2322
2344
writer
@@ -2358,6 +2380,8 @@ mod test {
2358
2380
alignment : 1 ,
2359
2381
#[ cfg( feature = "deflate-zopfli" ) ]
2360
2382
zopfli_buffer_size : None ,
2383
+ #[ cfg( feature = "aes-crypto" ) ]
2384
+ aes_mode : None ,
2361
2385
} ;
2362
2386
2363
2387
// GB18030
@@ -2411,6 +2435,8 @@ mod test {
2411
2435
alignment : 0 ,
2412
2436
#[ cfg( feature = "deflate-zopfli" ) ]
2413
2437
zopfli_buffer_size : None ,
2438
+ #[ cfg( feature = "aes-crypto" ) ]
2439
+ aes_mode : None ,
2414
2440
} ;
2415
2441
writer. start_file ( RT_TEST_FILENAME , options) . unwrap ( ) ;
2416
2442
writer. write_all ( RT_TEST_TEXT . as_ref ( ) ) . unwrap ( ) ;
@@ -2462,6 +2488,8 @@ mod test {
2462
2488
alignment : 0 ,
2463
2489
#[ cfg( feature = "deflate-zopfli" ) ]
2464
2490
zopfli_buffer_size : None ,
2491
+ #[ cfg( feature = "aes-crypto" ) ]
2492
+ aes_mode : None ,
2465
2493
} ;
2466
2494
writer. start_file ( RT_TEST_FILENAME , options) . unwrap ( ) ;
2467
2495
writer. write_all ( RT_TEST_TEXT . as_ref ( ) ) . unwrap ( ) ;
0 commit comments