Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change ZipOutputStream.CloseEntry() to work for AES encrypted Stored entries #323

Merged
merged 2 commits into from
Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,10 @@ protected override void Dispose(bool disposing)
}
}

private void GetAuthCodeIfAES()
/// <summary>
/// Get the Auth code for AES encrypted entries
/// </summary>
protected void GetAuthCodeIfAES()
{
if (cryptoTransform_ is ZipAESTransform)
{
Expand Down
6 changes: 6 additions & 0 deletions src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,12 @@ public void CloseEntry()
deflater_.Reset();
}
}
else if (curMethod == CompressionMethod.Stored)
{
// This is done by Finsh() for Deflated entries, but we need to do it
// ourselves for Stored ones
base.GetAuthCodeIfAES();
}

// Write the AES Authentication Code (a hash of the compressed and encrypted data)
if (curEntry.AESKeySize > 0)
Expand Down
64 changes: 61 additions & 3 deletions test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public void Aes128Encryption()
CreateZipWithEncryptedEntries("foo", 128);
}

[Test]
[Category("Encryption")]
[Category("Zip")]
public void Aes128EncryptionStored()
{
CreateZipWithEncryptedEntries("foo", 128, CompressionMethod.Stored);
}

[Test]
[Category("Encryption")]
[Category("Zip")]
Expand All @@ -27,6 +35,14 @@ public void Aes256Encryption()
CreateZipWithEncryptedEntries("foo", 256);
}

[Test]
[Category("Encryption")]
[Category("Zip")]
public void Aes256EncryptionStored()
{
CreateZipWithEncryptedEntries("foo", 256, CompressionMethod.Stored);
}

[Test]
[Category("Encryption")]
[Category("Zip")]
Expand Down Expand Up @@ -88,6 +104,47 @@ public void ZipFileAesRead()
}
}

/// <summary>
/// Test using AES encryption on a file whose contents are Stored rather than deflated
/// </summary>
[Test]
[Category("Encryption")]
[Category("Zip")]
public void ZipFileStoreAes()
{
string password = "password";

using (var memoryStream = new MemoryStream())
{
// Try to create a zip stream
WriteEncryptedZipToStream(memoryStream, password, 256, CompressionMethod.Stored);

// reset
memoryStream.Seek(0, SeekOrigin.Begin);

// try to read it
var zipFile = new ZipFile(memoryStream, leaveOpen: true)
{
Password = password
};

foreach (ZipEntry entry in zipFile)
{
if (!entry.IsFile) continue;

// Should be stored rather than deflated
Assert.That(entry.CompressionMethod, Is.EqualTo(CompressionMethod.Stored), "Entry should be stored");

using (var zis = zipFile.GetInputStream(entry))
using (var sr = new StreamReader(zis, Encoding.UTF8))
{
var content = sr.ReadToEnd();
Assert.That(content, Is.EqualTo(DummyDataString), "Decompressed content does not match input data");
}
}
}
}

private static readonly string[] possible7zPaths = new[] {
// Check in PATH
"7z", "7za",
Expand Down Expand Up @@ -135,7 +192,7 @@ public static bool TryGet7zBinPath(out string path7z)
return false;
}

public void WriteEncryptedZipToStream(Stream stream, string password, int keySize)
public void WriteEncryptedZipToStream(Stream stream, string password, int keySize, CompressionMethod compressionMethod = CompressionMethod.Deflated)
{
using (var zs = new ZipOutputStream(stream))
{
Expand All @@ -146,6 +203,7 @@ public void WriteEncryptedZipToStream(Stream stream, string password, int keySiz
ZipEntry zipEntry = new ZipEntry("test");
zipEntry.AESKeySize = keySize;
zipEntry.DateTime = DateTime.Now;
zipEntry.CompressionMethod = compressionMethod;

zs.PutNextEntry(zipEntry);

Expand All @@ -160,11 +218,11 @@ public void WriteEncryptedZipToStream(Stream stream, string password, int keySiz
}
}

public void CreateZipWithEncryptedEntries(string password, int keySize)
public void CreateZipWithEncryptedEntries(string password, int keySize, CompressionMethod compressionMethod = CompressionMethod.Deflated)
{
using (var ms = new MemoryStream())
{
WriteEncryptedZipToStream(ms, password, keySize);
WriteEncryptedZipToStream(ms, password, keySize, compressionMethod);

if (TryGet7zBinPath(out string path7z))
{
Expand Down