120 lines
3.1 KiB
C#
120 lines
3.1 KiB
C#
|
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();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|