-
Notifications
You must be signed in to change notification settings - Fork 474
/
RarCryptoWrapper.cs
82 lines (64 loc) · 2.28 KB
/
RarCryptoWrapper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Crypto;
namespace SharpCompress.Common.Rar;
internal sealed class RarCryptoWrapper : Stream
{
private readonly Stream _actualStream;
private BlockTransformer _rijndael;
private readonly Queue<byte> _data = new Queue<byte>();
public RarCryptoWrapper(Stream actualStream, byte[] salt, ICryptKey key)
{
_actualStream = actualStream;
_rijndael = new BlockTransformer(key.Transformer(salt));
}
public override void Flush() { }
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
public override void SetLength(long value) => throw new NotSupportedException();
public override int Read(byte[] buffer, int offset, int count)
{
return ReadAndDecrypt(buffer, offset, count);
}
public int ReadAndDecrypt(byte[] buffer, int offset, int count)
{
var queueSize = _data.Count;
var sizeToRead = count - queueSize;
if (sizeToRead > 0)
{
var alignedSize = sizeToRead + ((~sizeToRead + 1) & 0xf);
Span<byte> cipherText = stackalloc byte[16];
for (var i = 0; i < alignedSize / 16; i++)
{
//long ax = System.currentTimeMillis();
_actualStream.Read(cipherText);
var readBytes = _rijndael.ProcessBlock(cipherText);
foreach (var readByte in readBytes)
{
_data.Enqueue(readByte);
}
}
for (var i = 0; i < count; i++)
{
buffer[offset + i] = _data.Dequeue();
}
}
return count;
}
public override void Write(byte[] buffer, int offset, int count) =>
throw new NotSupportedException();
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length => throw new NotSupportedException();
public override long Position { get; set; }
protected override void Dispose(bool disposing)
{
if (_rijndael != null)
{
_rijndael.Dispose();
_rijndael = null!;
}
base.Dispose(disposing);
}
}