Skip to content
Permalink
Browse files

Merge PR #323: Fix ZipOutputStream.CloseEntry for AES encrypted Store…

…d 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
  • Loading branch information...
Numpsy authored and piksel committed Mar 4, 2019
1 parent 25ee644 commit afcccb09488ac2cd0ed701b52b17a5959dee5a41
@@ -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)
{
@@ -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)
@@ -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")]
@@ -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")]
@@ -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",
@@ -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))
{
@@ -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);

@@ -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))
{

0 comments on commit afcccb0

Please sign in to comment.
You can’t perform that action at this time.