Files
sharpcompress/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs
2013-11-23 11:10:07 +00:00

81 lines
2.2 KiB
C#

using System.Collections.Generic;
using System.IO;
using SharpCompress.IO;
namespace SharpCompress.Common.Rar
{
internal class RarCryptoBinaryReader : MarkingBinaryReader
{
private RarRijndael rijndael;
private byte[] salt;
private readonly string password;
private readonly Queue<byte> data = new Queue<byte>();
public RarCryptoBinaryReader(Stream stream, string password )
: base(stream)
{
this.password = password;
}
protected bool UseEncryption
{
get { return salt != null; }
}
internal void InitializeAes(byte[] salt)
{
this.salt = salt;
rijndael = RarRijndael.InitializeFrom(password, salt);
}
public override byte[] ReadBytes(int count)
{
if (UseEncryption)
{
return ReadAndDecryptBytes(count);
}
return base.ReadBytes(count);
}
private byte[] ReadAndDecryptBytes(int count)
{
int queueSize = data.Count;
int sizeToRead = count - queueSize;
if (sizeToRead > 0)
{
int alignedSize = sizeToRead + ((~sizeToRead + 1) & 0xf);
for (int i = 0; i < alignedSize / 16; i++)
{
//long ax = System.currentTimeMillis();
byte[] cipherText = base.ReadBytes(16);
var readBytes = rijndael.ProcessBlock(cipherText);
foreach (var readByte in readBytes)
data.Enqueue(readByte);
}
}
var decryptedBytes = new byte[count];
for (int i = 0; i < count; i++)
{
decryptedBytes[i] = data.Dequeue();
}
return decryptedBytes;
}
public void ClearQueue()
{
data.Clear();
}
public void SkipQueue()
{
var position = BaseStream.Position;
BaseStream.Position = position + data.Count;
ClearQueue();
}
}
}