Skip to content

Commit afcccb0

Browse files
Numpsypiksel
authored andcommitted
Merge PR icsharpcode#323: Fix ZipOutputStream.CloseEntry for AES encrypted Stored entries
* Fix ZipOutputStream.CloseEntry() to work for Stored AES encrypted entries * Add unit tests for AES encrypted zips whose contents are Stored rather than Deflated
1 parent 25ee644 commit afcccb0

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,10 @@ protected override void Dispose(bool disposing)
414414
}
415415
}
416416

417-
private void GetAuthCodeIfAES()
417+
/// <summary>
418+
/// Get the Auth code for AES encrypted entries
419+
/// </summary>
420+
protected void GetAuthCodeIfAES()
418421
{
419422
if (cryptoTransform_ is ZipAESTransform)
420423
{

src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,12 @@ public void CloseEntry()
486486
deflater_.Reset();
487487
}
488488
}
489+
else if (curMethod == CompressionMethod.Stored)
490+
{
491+
// This is done by Finsh() for Deflated entries, but we need to do it
492+
// ourselves for Stored ones
493+
base.GetAuthCodeIfAES();
494+
}
489495

490496
// Write the AES Authentication Code (a hash of the compressed and encrypted data)
491497
if (curEntry.AESKeySize > 0)

test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ public void Aes128Encryption()
1919
CreateZipWithEncryptedEntries("foo", 128);
2020
}
2121

22+
[Test]
23+
[Category("Encryption")]
24+
[Category("Zip")]
25+
public void Aes128EncryptionStored()
26+
{
27+
CreateZipWithEncryptedEntries("foo", 128, CompressionMethod.Stored);
28+
}
29+
2230
[Test]
2331
[Category("Encryption")]
2432
[Category("Zip")]
@@ -27,6 +35,14 @@ public void Aes256Encryption()
2735
CreateZipWithEncryptedEntries("foo", 256);
2836
}
2937

38+
[Test]
39+
[Category("Encryption")]
40+
[Category("Zip")]
41+
public void Aes256EncryptionStored()
42+
{
43+
CreateZipWithEncryptedEntries("foo", 256, CompressionMethod.Stored);
44+
}
45+
3046
[Test]
3147
[Category("Encryption")]
3248
[Category("Zip")]
@@ -88,6 +104,47 @@ public void ZipFileAesRead()
88104
}
89105
}
90106

107+
/// <summary>
108+
/// Test using AES encryption on a file whose contents are Stored rather than deflated
109+
/// </summary>
110+
[Test]
111+
[Category("Encryption")]
112+
[Category("Zip")]
113+
public void ZipFileStoreAes()
114+
{
115+
string password = "password";
116+
117+
using (var memoryStream = new MemoryStream())
118+
{
119+
// Try to create a zip stream
120+
WriteEncryptedZipToStream(memoryStream, password, 256, CompressionMethod.Stored);
121+
122+
// reset
123+
memoryStream.Seek(0, SeekOrigin.Begin);
124+
125+
// try to read it
126+
var zipFile = new ZipFile(memoryStream, leaveOpen: true)
127+
{
128+
Password = password
129+
};
130+
131+
foreach (ZipEntry entry in zipFile)
132+
{
133+
if (!entry.IsFile) continue;
134+
135+
// Should be stored rather than deflated
136+
Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.Stored), "Entry should be stored");
137+
138+
using (var zis = zipFile.GetInputStream(entry))
139+
using (var sr = new StreamReader(zis, Encoding.UTF8))
140+
{
141+
var content = sr.ReadToEnd();
142+
Assert.That(content, Is.EqualTo(DummyDataString), "Decompressed content does not match input data");
143+
}
144+
}
145+
}
146+
}
147+
91148
private static readonly string[] possible7zPaths = new[] {
92149
// Check in PATH
93150
"7z", "7za",
@@ -135,7 +192,7 @@ public static bool TryGet7zBinPath(out string path7z)
135192
return false;
136193
}
137194

138-
public void WriteEncryptedZipToStream(Stream stream, string password, int keySize)
195+
public void WriteEncryptedZipToStream(Stream stream, string password, int keySize, CompressionMethod compressionMethod = CompressionMethod.Deflated)
139196
{
140197
using (var zs = new ZipOutputStream(stream))
141198
{
@@ -146,6 +203,7 @@ public void WriteEncryptedZipToStream(Stream stream, string password, int keySiz
146203
ZipEntry zipEntry = new ZipEntry("test");
147204
zipEntry.AESKeySize = keySize;
148205
zipEntry.DateTime = DateTime.Now;
206+
zipEntry.CompressionMethod = compressionMethod;
149207

150208
zs.PutNextEntry(zipEntry);
151209

@@ -160,11 +218,11 @@ public void WriteEncryptedZipToStream(Stream stream, string password, int keySiz
160218
}
161219
}
162220

163-
public void CreateZipWithEncryptedEntries(string password, int keySize)
221+
public void CreateZipWithEncryptedEntries(string password, int keySize, CompressionMethod compressionMethod = CompressionMethod.Deflated)
164222
{
165223
using (var ms = new MemoryStream())
166224
{
167-
WriteEncryptedZipToStream(ms, password, keySize);
225+
WriteEncryptedZipToStream(ms, password, keySize, compressionMethod);
168226

169227
if (TryGet7zBinPath(out string path7z))
170228
{

0 commit comments

Comments
 (0)