Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
using System.IO;
namespace SharpCompress.Common.Zip.Headers
{
internal class DirectoryEndHeader : ZipHeader
{
public DirectoryEndHeader()
: base(ZipHeaderType.DirectoryEnd)
{
}
internal override void Read(BinaryReader reader)
{
VolumeNumber = reader.ReadUInt16();
FirstVolumeWithDirectory = reader.ReadUInt16();
TotalNumberOfEntriesInDisk = reader.ReadUInt16();
TotalNumberOfEntries = reader.ReadUInt16();
DirectorySize = reader.ReadUInt32();
DirectoryStartOffsetRelativeToDisk = reader.ReadUInt32();
CommentLength = reader.ReadUInt16();
Comment = reader.ReadBytes(CommentLength);
}
internal override void Write(BinaryWriter writer)
{
writer.Write(VolumeNumber);
writer.Write(FirstVolumeWithDirectory);
writer.Write(TotalNumberOfEntriesInDisk);
writer.Write(TotalNumberOfEntries);
writer.Write(DirectorySize);
writer.Write(DirectoryStartOffsetRelativeToDisk);
writer.Write(CommentLength);
writer.Write(Comment);
}
public ushort VolumeNumber { get; private set; }
public ushort FirstVolumeWithDirectory { get; private set; }
public ushort TotalNumberOfEntriesInDisk { get; private set; }
public uint DirectorySize { get; private set; }
public uint DirectoryStartOffsetRelativeToDisk { get; private set; }
public ushort CommentLength { get; private set; }
public byte[] Comment { get; private set; }
public ushort TotalNumberOfEntries { get; private set; }
}
}

View File

@@ -0,0 +1,81 @@
using System.IO;
namespace SharpCompress.Common.Zip.Headers
{
internal class DirectoryEntryHeader : ZipFileEntry
{
public DirectoryEntryHeader()
: base(ZipHeaderType.DirectoryEntry)
{
}
internal override void Read(BinaryReader reader)
{
Version = reader.ReadUInt16();
VersionNeededToExtract = reader.ReadUInt16();
Flags = (HeaderFlags) reader.ReadUInt16();
CompressionMethod = (ZipCompressionMethod) reader.ReadUInt16();
LastModifiedTime = reader.ReadUInt16();
LastModifiedDate = reader.ReadUInt16();
Crc = reader.ReadUInt32();
CompressedSize = reader.ReadUInt32();
UncompressedSize = reader.ReadUInt32();
ushort nameLength = reader.ReadUInt16();
ushort extraLength = reader.ReadUInt16();
ushort commentLength = reader.ReadUInt16();
DiskNumberStart = reader.ReadUInt16();
InternalFileAttributes = reader.ReadUInt16();
ExternalFileAttributes = reader.ReadUInt32();
RelativeOffsetOfEntryHeader = reader.ReadUInt32();
byte[] name = reader.ReadBytes(nameLength);
Name = DecodeString(name);
byte[] extra = reader.ReadBytes(extraLength);
byte[] comment = reader.ReadBytes(commentLength);
Comment = DecodeString(comment);
LoadExtra(extra);
}
internal override void Write(BinaryWriter writer)
{
writer.Write(Version);
writer.Write(VersionNeededToExtract);
writer.Write((ushort) Flags);
writer.Write((ushort) CompressionMethod);
writer.Write(LastModifiedTime);
writer.Write(LastModifiedDate);
writer.Write(Crc);
writer.Write(CompressedSize);
writer.Write(UncompressedSize);
byte[] nameBytes = EncodeString(Name);
writer.Write((ushort) nameBytes.Length);
//writer.Write((ushort)Extra.Length);
writer.Write((ushort) 0);
writer.Write((ushort) Comment.Length);
writer.Write(DiskNumberStart);
writer.Write(InternalFileAttributes);
writer.Write(ExternalFileAttributes);
writer.Write(RelativeOffsetOfEntryHeader);
writer.Write(nameBytes);
// writer.Write(Extra);
writer.Write(Comment);
}
internal ushort Version { get; private set; }
public ushort VersionNeededToExtract { get; set; }
public uint RelativeOffsetOfEntryHeader { get; set; }
public uint ExternalFileAttributes { get; set; }
public ushort InternalFileAttributes { get; set; }
public ushort DiskNumberStart { get; set; }
public string Comment { get; private set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace SharpCompress.Common.Zip.Headers
{
[Flags]
internal enum HeaderFlags : ushort
{
Encrypted = 1, // http://www.pkware.com/documents/casestudies/APPNOTE.TXT
Bit1 = 2,
Bit2 = 4,
UsePostDataDescriptor = 8,
EnhancedDeflate = 16,
UTF8 = 2048
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.IO;
namespace SharpCompress.Common.Zip.Headers
{
internal class IgnoreHeader : ZipHeader
{
public IgnoreHeader(ZipHeaderType type)
: base(type)
{
}
internal override void Read(BinaryReader reader)
{
}
internal override void Write(BinaryWriter writer)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,66 @@
using System.IO;
namespace SharpCompress.Common.Zip.Headers
{
internal enum ExtraDataType : ushort
{
WinZipAes = 0x9901,
}
internal class ExtraData
{
internal ExtraDataType Type { get; set; }
internal ushort Length { get; set; }
internal byte[] DataBytes { get; set; }
}
internal class LocalEntryHeader : ZipFileEntry
{
public LocalEntryHeader()
: base(ZipHeaderType.LocalEntry)
{
}
internal override void Read(BinaryReader reader)
{
Version = reader.ReadUInt16();
Flags = (HeaderFlags) reader.ReadUInt16();
CompressionMethod = (ZipCompressionMethod) reader.ReadUInt16();
LastModifiedTime = reader.ReadUInt16();
LastModifiedDate = reader.ReadUInt16();
Crc = reader.ReadUInt32();
CompressedSize = reader.ReadUInt32();
UncompressedSize = reader.ReadUInt32();
ushort nameLength = reader.ReadUInt16();
ushort extraLength = reader.ReadUInt16();
byte[] name = reader.ReadBytes(nameLength);
byte[] extra = reader.ReadBytes(extraLength);
Name = DecodeString(name);
LoadExtra(extra);
}
internal override void Write(BinaryWriter writer)
{
writer.Write(Version);
writer.Write((ushort) Flags);
writer.Write((ushort) CompressionMethod);
writer.Write(LastModifiedTime);
writer.Write(LastModifiedDate);
writer.Write(Crc);
writer.Write(CompressedSize);
writer.Write(UncompressedSize);
byte[] nameBytes = EncodeString(Name);
writer.Write((ushort) nameBytes.Length);
writer.Write((ushort) 0);
//if (Extra != null)
//{
// writer.Write(Extra);
//}
writer.Write(nameBytes);
}
internal ushort Version { get; private set; }
}
}

View File

@@ -0,0 +1,22 @@
using System;
namespace SharpCompress.Common.Zip.Headers
{
internal class SplitHeader : ZipHeader
{
public SplitHeader()
: base(ZipHeaderType.Split)
{
}
internal override void Read(System.IO.BinaryReader reader)
{
throw new NotImplementedException();
}
internal override void Write(System.IO.BinaryWriter writer)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace SharpCompress.Common.Zip.Headers
{
internal abstract class ZipFileEntry : ZipHeader
{
protected ZipFileEntry(ZipHeaderType type)
: base(type)
{
Extra = new List<ExtraData>();
}
internal bool IsDirectory
{
get { return Name.EndsWith("/"); }
}
protected string DecodeString(byte[] str)
{
if (FlagUtility.HasFlag(Flags, HeaderFlags.UTF8))
{
return Encoding.UTF8.GetString(str, 0, str.Length);
}
return ArchiveEncoding.Default.GetString(str, 0, str.Length);
}
protected byte[] EncodeString(string str)
{
if (FlagUtility.HasFlag(Flags, HeaderFlags.UTF8))
{
return Encoding.UTF8.GetBytes(str);
}
return ArchiveEncoding.Default.GetBytes(str);
}
internal Stream PackedStream { get; set; }
internal string Name { get; set; }
internal HeaderFlags Flags { get; set; }
internal ZipCompressionMethod CompressionMethod { get; set; }
internal uint CompressedSize { get; set; }
internal long? DataStartPosition { get; set; }
internal uint UncompressedSize { get; set; }
internal List<ExtraData> Extra { get; set; }
internal PkwareTraditionalEncryptionData PkwareTraditionalEncryptionData { get; set; }
#if !PORTABLE && !NETFX_CORE
internal WinzipAesEncryptionData WinzipAesEncryptionData { get; set; }
#endif
internal ushort LastModifiedDate { get; set; }
internal ushort LastModifiedTime { get; set; }
internal uint Crc { get; set; }
protected void LoadExtra(byte[] extra)
{
for (int i = 0; i < extra.Length;)
{
ExtraDataType type = (ExtraDataType) BitConverter.ToUInt16(extra, i);
if (!Enum.IsDefined(typeof (ExtraDataType), type))
{
return;
}
ushort length = BitConverter.ToUInt16(extra, i + 2);
byte[] data = new byte[length];
Buffer.BlockCopy(extra, i + 4, data, 0, length);
Extra.Add(new ExtraData
{
Type = type,
Length = length,
DataBytes = data
});
i += length + 4;
}
}
internal ZipFilePart Part { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using System.IO;
namespace SharpCompress.Common.Zip.Headers
{
internal abstract class ZipHeader
{
protected ZipHeader(ZipHeaderType type)
{
ZipHeaderType = type;
HasData = true;
}
internal ZipHeaderType ZipHeaderType { get; private set; }
internal abstract void Read(BinaryReader reader);
internal abstract void Write(BinaryWriter writer);
internal bool HasData { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
namespace SharpCompress.Common.Zip.Headers
{
internal enum ZipHeaderType
{
Ignore,
LocalEntry,
DirectoryEntry,
DirectoryEnd,
Split,
}
}

View File

@@ -0,0 +1,120 @@
using System;
using System.IO;
namespace SharpCompress.Common.Zip
{
internal enum CryptoMode
{
Encrypt,
Decrypt
}
internal class PkwareTraditionalCryptoStream : Stream
{
private readonly PkwareTraditionalEncryptionData encryptor;
private readonly CryptoMode mode;
private readonly Stream stream;
private bool isDisposed;
public PkwareTraditionalCryptoStream(Stream stream, PkwareTraditionalEncryptionData encryptor, CryptoMode mode)
{
this.encryptor = encryptor;
this.stream = stream;
this.mode = mode;
}
public override bool CanRead
{
get { return (mode == CryptoMode.Decrypt); }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return (mode == CryptoMode.Encrypt); }
}
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public override int Read(byte[] buffer, int offset, int count)
{
if (mode == CryptoMode.Encrypt)
throw new NotSupportedException("This stream does not encrypt via Read()");
if (buffer == null)
throw new ArgumentNullException("buffer");
byte[] temp = new byte[count];
int readBytes = stream.Read(temp, 0, count);
byte[] decrypted = encryptor.Decrypt(temp, readBytes);
Buffer.BlockCopy(decrypted, 0, buffer, offset, readBytes);
return readBytes;
}
public override void Write(byte[] buffer, int offset, int count)
{
if (mode == CryptoMode.Decrypt)
throw new NotSupportedException("This stream does not Decrypt via Write()");
if (count == 0)
{
return;
}
byte[] plaintext = null;
if (offset != 0)
{
plaintext = new byte[count];
Buffer.BlockCopy(buffer, offset, plaintext, 0, count);
}
else
{
plaintext = buffer;
}
byte[] encrypted = encryptor.Encrypt(plaintext, count);
stream.Write(encrypted, 0, encrypted.Length);
}
public override void Flush()
{
//throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
protected override void Dispose(bool disposing)
{
if (isDisposed)
{
return;
}
isDisposed = true;
base.Dispose(disposing);
stream.Dispose();
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Text;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.Compressor.Deflate;
namespace SharpCompress.Common.Zip
{
internal class PkwareTraditionalEncryptionData
{
private static readonly CRC32 crc32 = new CRC32();
private readonly UInt32[] _Keys = {0x12345678, 0x23456789, 0x34567890};
private PkwareTraditionalEncryptionData(string password)
{
Initialize(password);
}
private byte MagicByte
{
get
{
ushort t = (ushort) ((ushort) (_Keys[2] & 0xFFFF) | 2);
return (byte) ((t*(t ^ 1)) >> 8);
}
}
public static PkwareTraditionalEncryptionData ForRead(string password, ZipFileEntry header,
byte[] encryptionHeader)
{
var encryptor = new PkwareTraditionalEncryptionData(password);
byte[] plainTextHeader = encryptor.Decrypt(encryptionHeader, encryptionHeader.Length);
if (plainTextHeader[11] != (byte) ((header.Crc >> 24) & 0xff))
{
if (!FlagUtility.HasFlag(header.Flags, HeaderFlags.UsePostDataDescriptor))
{
throw new CryptographicException("The password did not match.");
}
if (plainTextHeader[11] != (byte) ((header.LastModifiedTime >> 8) & 0xff))
{
throw new CryptographicException("The password did not match.");
}
}
return encryptor;
}
public byte[] Decrypt(byte[] cipherText, int length)
{
if (length > cipherText.Length)
throw new ArgumentOutOfRangeException("length",
"Bad length during Decryption: the length parameter must be smaller than or equal to the size of the destination array.");
var plainText = new byte[length];
for (int i = 0; i < length; i++)
{
var C = (byte) (cipherText[i] ^ MagicByte);
UpdateKeys(C);
plainText[i] = C;
}
return plainText;
}
public byte[] Encrypt(byte[] plainText, int length)
{
if (plainText == null)
throw new ArgumentNullException("plaintext");
if (length > plainText.Length)
throw new ArgumentOutOfRangeException("length",
"Bad length during Encryption: The length parameter must be smaller than or equal to the size of the destination array.");
var cipherText = new byte[length];
for (int i = 0; i < length; i++)
{
byte C = plainText[i];
cipherText[i] = (byte) (plainText[i] ^ MagicByte);
UpdateKeys(C);
}
return cipherText;
}
private void Initialize(string password)
{
byte[] p = StringToByteArray(password);
for (int i = 0; i < password.Length; i++)
UpdateKeys(p[i]);
}
internal static byte[] StringToByteArray(string value, Encoding encoding)
{
byte[] a = encoding.GetBytes(value);
return a;
}
internal static byte[] StringToByteArray(string value)
{
return StringToByteArray(value, ArchiveEncoding.Password);
}
private void UpdateKeys(byte byteValue)
{
_Keys[0] = (UInt32) crc32.ComputeCrc32((int) _Keys[0], byteValue);
_Keys[1] = _Keys[1] + (byte) _Keys[0];
_Keys[1] = _Keys[1]*0x08088405 + 1;
_Keys[2] = (UInt32) crc32.ComputeCrc32((int) _Keys[2], (byte) (_Keys[1] >> 24));
}
}
}

View File

@@ -0,0 +1,45 @@
using System.IO;
using SharpCompress.Common.Zip.Headers;
namespace SharpCompress.Common.Zip
{
internal class SeekableZipFilePart : ZipFilePart
{
private bool isLocalHeaderLoaded;
private readonly SeekableZipHeaderFactory headerFactory;
internal SeekableZipFilePart(SeekableZipHeaderFactory headerFactory, DirectoryEntryHeader header, Stream stream)
: base(header, stream)
{
this.headerFactory = headerFactory;
}
internal override Stream GetCompressedStream()
{
if (!isLocalHeaderLoaded)
{
LoadLocalHeader();
isLocalHeaderLoaded = true;
}
return base.GetCompressedStream();
}
internal string Comment
{
get { return (Header as DirectoryEntryHeader).Comment; }
}
private void LoadLocalHeader()
{
bool hasData = Header.HasData;
Header = headerFactory.GetLocalHeader(BaseStream, Header as DirectoryEntryHeader);
Header.HasData = hasData;
}
protected override Stream CreateBaseStream()
{
BaseStream.Position = Header.DataStartPosition.Value;
return BaseStream;
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
namespace SharpCompress.Common.Zip
{
internal class SeekableZipHeaderFactory : ZipHeaderFactory
{
private const int MAX_ITERATIONS_FOR_DIRECTORY_HEADER = 1000;
internal SeekableZipHeaderFactory(string password)
: base(StreamingMode.Seekable, password)
{
}
internal IEnumerable<DirectoryEntryHeader> ReadSeekableHeader(Stream stream)
{
long offset = 0;
uint signature;
BinaryReader reader = new BinaryReader(stream);
int iterationCount = 0;
do
{
if ((stream.Length + offset) - 4 < 0)
{
throw new ArchiveException("Failed to locate the Zip Header");
}
stream.Seek(offset - 4, SeekOrigin.End);
signature = reader.ReadUInt32();
offset--;
iterationCount++;
if (iterationCount > MAX_ITERATIONS_FOR_DIRECTORY_HEADER)
{
throw new ArchiveException(
"Could not find Zip file Directory at the end of the file. File may be corrupted.");
}
} while (signature != DIRECTORY_END_HEADER_BYTES);
var entry = new DirectoryEndHeader();
entry.Read(reader);
stream.Seek(entry.DirectoryStartOffsetRelativeToDisk, SeekOrigin.Begin);
DirectoryEntryHeader directoryEntryHeader = null;
long position = stream.Position;
while (true)
{
stream.Position = position;
signature = reader.ReadUInt32();
directoryEntryHeader = ReadHeader(signature, reader) as DirectoryEntryHeader;
position = stream.Position;
if (directoryEntryHeader == null)
{
yield break;
}
//entry could be zero bytes so we need to know that.
directoryEntryHeader.HasData = directoryEntryHeader.CompressedSize != 0;
yield return directoryEntryHeader;
}
}
internal LocalEntryHeader GetLocalHeader(Stream stream, DirectoryEntryHeader directoryEntryHeader)
{
stream.Seek(directoryEntryHeader.RelativeOffsetOfEntryHeader, SeekOrigin.Begin);
BinaryReader reader = new BinaryReader(stream);
uint signature = reader.ReadUInt32();
var localEntryHeader = ReadHeader(signature, reader) as LocalEntryHeader;
if (localEntryHeader == null)
{
throw new InvalidOperationException();
}
return localEntryHeader;
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.IO;
using System.IO.Compression;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
namespace SharpCompress.Common.Zip
{
internal class StreamingZipFilePart : ZipFilePart
{
private Stream decompressionStream;
internal StreamingZipFilePart(ZipFileEntry header, Stream stream)
: base(header, stream)
{
}
protected override Stream CreateBaseStream()
{
return Header.PackedStream;
}
internal override Stream GetCompressedStream()
{
if (!Header.HasData)
{
return Stream.Null;
}
decompressionStream = CreateDecompressionStream(GetCryptoStream(CreateBaseStream()));
if (LeaveStreamOpen)
{
return new NonDisposingStream(decompressionStream);
}
return decompressionStream;
}
internal BinaryReader FixStreamedFileLocation(ref RewindableStream rewindableStream)
{
if (Header.IsDirectory)
{
return new BinaryReader(rewindableStream);
}
if (Header.HasData)
{
if (decompressionStream == null)
{
decompressionStream = GetCompressedStream();
}
decompressionStream.SkipAll();
DeflateStream deflateStream = decompressionStream as DeflateStream;
if (deflateStream != null)
{
rewindableStream.Rewind(deflateStream.BaseStream as MemoryStream);
}
}
var reader = new BinaryReader(rewindableStream);
decompressionStream = null;
return reader;
}
}
}

View File

@@ -0,0 +1,65 @@
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
namespace SharpCompress.Common.Zip
{
internal class StreamingZipHeaderFactory : ZipHeaderFactory
{
internal StreamingZipHeaderFactory(string password)
: base(StreamingMode.Streaming, password)
{
}
internal IEnumerable<ZipHeader> ReadStreamHeader(Stream stream)
{
RewindableStream rewindableStream;
if (stream is RewindableStream)
{
rewindableStream = stream as RewindableStream;
}
else
{
rewindableStream = new RewindableStream(stream);
}
while (true)
{
ZipHeader header = null;
BinaryReader reader = new BinaryReader(rewindableStream);
if (lastEntryHeader != null &&
FlagUtility.HasFlag(lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor))
{
reader = (lastEntryHeader.Part as StreamingZipFilePart).FixStreamedFileLocation(ref rewindableStream);
long pos = rewindableStream.Position;
uint crc = reader.ReadUInt32();
if (crc == POST_DATA_DESCRIPTOR)
{
crc = reader.ReadUInt32();
}
lastEntryHeader.Crc = crc;
lastEntryHeader.CompressedSize = reader.ReadUInt32();
lastEntryHeader.UncompressedSize = reader.ReadUInt32();
lastEntryHeader.DataStartPosition = pos - lastEntryHeader.CompressedSize;
}
lastEntryHeader = null;
uint headerBytes = reader.ReadUInt32();
header = ReadHeader(headerBytes, reader);
//entry could be zero bytes so we need to know that.
if (header.ZipHeaderType == ZipHeaderType.LocalEntry)
{
bool isRecording = rewindableStream.IsRecording;
if (!isRecording)
{
rewindableStream.StartRecording();
}
uint nextHeaderBytes = reader.ReadUInt32();
header.HasData = !IsHeader(nextHeaderBytes);
rewindableStream.Rewind(!isRecording);
}
yield return header;
}
}
}
}

View File

@@ -0,0 +1,180 @@
using System;
using System.IO;
using System.Security.Cryptography;
namespace SharpCompress.Common.Zip
{
internal class WinzipAesCryptoStream : Stream
{
private const int BLOCK_SIZE_IN_BYTES = 16;
private readonly SymmetricAlgorithm cipher;
private readonly byte[] counter = new byte[BLOCK_SIZE_IN_BYTES];
private readonly Stream stream;
private readonly ICryptoTransform transform;
private int nonce = 1;
private byte[] counterOut = new byte[BLOCK_SIZE_IN_BYTES];
private bool isFinalBlock;
private long totalBytesLeftToRead;
private bool isDisposed;
internal WinzipAesCryptoStream(Stream stream, WinzipAesEncryptionData winzipAesEncryptionData, long length)
{
this.stream = stream;
totalBytesLeftToRead = length;
cipher = CreateCipher(winzipAesEncryptionData);
var iv = new byte[BLOCK_SIZE_IN_BYTES];
transform = cipher.CreateEncryptor(winzipAesEncryptionData.KeyBytes, iv);
}
private SymmetricAlgorithm CreateCipher(WinzipAesEncryptionData winzipAesEncryptionData)
{
RijndaelManaged cipher = new RijndaelManaged();
cipher.BlockSize = BLOCK_SIZE_IN_BYTES * 8;
cipher.KeySize = winzipAesEncryptionData.KeyBytes.Length * 8;
cipher.Mode = CipherMode.ECB;
cipher.Padding = PaddingMode.None;
return cipher;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return false; }
}
public override long Length
{
get { throw new NotImplementedException(); }
}
public override long Position
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
protected override void Dispose(bool disposing)
{
if (isDisposed)
{
return;
}
isDisposed = true;
if (disposing)
{
//read out last 10 auth bytes
var ten = new byte[10];
stream.Read(ten, 0, 10);
stream.Dispose();
}
}
public override void Flush()
{
throw new NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
if (totalBytesLeftToRead == 0)
{
return 0;
}
int bytesToRead = count;
if (count > totalBytesLeftToRead)
{
bytesToRead = (int)totalBytesLeftToRead;
}
int read = stream.Read(buffer, offset, bytesToRead);
totalBytesLeftToRead -= read;
ReadTransformBlocks(buffer, offset, read);
return read;
}
private int ReadTransformOneBlock(byte[] buffer, int offset, int last)
{
if (isFinalBlock)
{
throw new InvalidOperationException();
}
int bytesRemaining = last - offset;
int bytesToRead = (bytesRemaining > BLOCK_SIZE_IN_BYTES)
? BLOCK_SIZE_IN_BYTES
: bytesRemaining;
// update the counter
Array.Copy(BitConverter.GetBytes(nonce++), 0, counter, 0, 4);
// Determine if this is the final block
if ((bytesToRead == bytesRemaining) && (totalBytesLeftToRead == 0))
{
counterOut = transform.TransformFinalBlock(counter,
0,
BLOCK_SIZE_IN_BYTES);
isFinalBlock = true;
}
else
{
transform.TransformBlock(counter,
0, // offset
BLOCK_SIZE_IN_BYTES,
counterOut,
0); // offset
}
XorInPlace(buffer, offset, bytesToRead);
return bytesToRead;
}
private void XorInPlace(byte[] buffer, int offset, int count)
{
for (int i = 0; i < count; i++)
{
buffer[offset + i] = (byte)(counterOut[i] ^ buffer[offset + i]);
}
}
private void ReadTransformBlocks(byte[] buffer, int offset, int count)
{
int posn = offset;
int last = count + offset;
while (posn < buffer.Length && posn < last)
{
int n = ReadTransformOneBlock(buffer, posn, last);
posn += n;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,66 @@
using System;
namespace SharpCompress.Common.Zip
{
internal class WinzipAesEncryptionData
{
private const int RFC2898_ITERATIONS = 1000;
private byte[] salt;
private WinzipAesKeySize keySize;
private byte[] passwordVerifyValue;
private string password;
private byte[] generatedVerifyValue;
internal WinzipAesEncryptionData(WinzipAesKeySize keySize, byte[] salt, byte[] passwordVerifyValue,
string password)
{
this.keySize = keySize;
this.salt = salt;
this.passwordVerifyValue = passwordVerifyValue;
this.password = password;
Initialize();
}
internal byte[] IvBytes { get; set; }
internal byte[] KeyBytes { get; set; }
private int KeySizeInBytes
{
get { return KeyLengthInBytes(keySize); }
}
internal static int KeyLengthInBytes(WinzipAesKeySize keySize)
{
switch (keySize)
{
case WinzipAesKeySize.KeySize128:
return 16;
case WinzipAesKeySize.KeySize192:
return 24;
case WinzipAesKeySize.KeySize256:
return 32;
}
throw new InvalidOperationException();
}
private void Initialize()
{
System.Security.Cryptography.Rfc2898DeriveBytes rfc2898 =
new System.Security.Cryptography.Rfc2898DeriveBytes(password, salt, RFC2898_ITERATIONS);
KeyBytes = rfc2898.GetBytes(KeySizeInBytes); // 16 or 24 or 32 ???
IvBytes = rfc2898.GetBytes(KeySizeInBytes);
generatedVerifyValue = rfc2898.GetBytes(2);
short verify = BitConverter.ToInt16(passwordVerifyValue, 0);
if (password != null)
{
short generated = BitConverter.ToInt16(generatedVerifyValue, 0);
if (verify != generated)
throw new InvalidFormatException("bad password");
}
}
}
}

View File

@@ -0,0 +1,9 @@
namespace SharpCompress.Common.Zip
{
internal enum WinzipAesKeySize
{
KeySize128 = 1,
KeySize192 = 2,
KeySize256 = 3,
}
}

View File

@@ -0,0 +1,13 @@
namespace SharpCompress.Common.Zip
{
internal enum ZipCompressionMethod
{
None = 0,
Deflate = 8,
Deflate64 = 9,
BZip2 = 12,
LZMA = 14,
PPMd = 98,
WinzipAes = 0x63 //http://www.winzip.com/aes_info.htm
}
}

View File

@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using SharpCompress.Common.Zip.Headers;
namespace SharpCompress.Common.Zip
{
internal class ZipEntry : Entry
{
private readonly ZipFilePart filePart;
private DateTime? lastModifiedTime;
internal ZipEntry(ZipFilePart filePart)
{
if (filePart != null)
{
this.filePart = filePart;
lastModifiedTime = Utility.DosDateToDateTime(filePart.Header.LastModifiedDate,
filePart.Header.LastModifiedTime);
}
}
public override CompressionType CompressionType
{
get
{
switch (filePart.Header.CompressionMethod)
{
case ZipCompressionMethod.BZip2:
{
return CompressionType.BZip2;
}
case ZipCompressionMethod.Deflate:
{
return CompressionType.Deflate;
}
case ZipCompressionMethod.LZMA:
{
return CompressionType.LZMA;
}
case ZipCompressionMethod.PPMd:
{
return CompressionType.PPMd;
}
case ZipCompressionMethod.None:
{
return CompressionType.None;
}
default:
{
return CompressionType.Unknown;
}
}
}
}
public override uint Crc
{
get { return filePart.Header.Crc; }
}
public override string Key
{
get { return filePart.Header.Name; }
}
public override long CompressedSize
{
get { return filePart.Header.CompressedSize; }
}
public override long Size
{
get { return filePart.Header.UncompressedSize; }
}
public override DateTime? LastModifiedTime
{
get { return lastModifiedTime; }
set { lastModifiedTime = value; }
}
public override DateTime? CreatedTime
{
get { return null; }
}
public override DateTime? LastAccessedTime
{
get { return null; }
}
public override DateTime? ArchivedTime
{
get { return null; }
}
public override bool IsEncrypted
{
get { return FlagUtility.HasFlag(filePart.Header.Flags, HeaderFlags.Encrypted); }
}
public override bool IsDirectory
{
get { return filePart.Header.IsDirectory; }
}
public override bool IsSplit
{
get { return false; }
}
internal override IEnumerable<FilePart> Parts
{
get { return filePart.AsEnumerable<FilePart>(); }
}
}
}

Some files were not shown because too many files have changed in this diff Show More