Skip to content

Commit bb89dfb

Browse files
committed
added password raw and comment raw (for transport streams)
1 parent f4967f0 commit bb89dfb

File tree

9 files changed

+167
-38
lines changed

9 files changed

+167
-38
lines changed

Blazer.Net.Tests/EncryptionTests.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,6 @@ public void Check_Encrypt_Peformance()
196196
[Test]
197197
public void Duplicate_Data_Blocks_Should_Be_Catched_on_Decryption()
198198
{
199-
var data = Encoding.UTF8.GetBytes("some compressible not very long string. some some some.");
200199
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
201200
blazerCompressionOptions.SetEncoderByAlgorithm(BlazerAlgorithm.NoCompress);
202201
blazerCompressionOptions.Password = "123";
@@ -227,5 +226,29 @@ public void Duplicate_Data_Blocks_Should_Be_Catched_on_Decryption()
227226
var os = new BlazerOutputStream(stream2, new BlazerDecompressionOptions("123"));
228227
Assert.Throws<InvalidOperationException>(() => os.CopyTo(new MemoryStream()), "Invalid encrypted block. Duplicated or damaged.");
229228
}
229+
230+
[Test]
231+
public void Password_Raw_Should_Be_Processed()
232+
{
233+
var data = Encoding.UTF8.GetBytes("some compressible not very long string. some some some.");
234+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
235+
blazerCompressionOptions.SetEncoderByAlgorithm(BlazerAlgorithm.Stream);
236+
blazerCompressionOptions.PasswordRaw = new byte[] { 1, 2, 3 };
237+
blazerCompressionOptions.FlushMode = BlazerFlushMode.AutoFlush;
238+
IntegrityHelper.CheckCompressDecompress(data, blazerCompressionOptions, s => new BlazerOutputStream(s, new BlazerDecompressionOptions(new byte[] { 1, 2, 3 })));
239+
}
240+
241+
[Test]
242+
public void Password_Raw_Should_Be_Equal_To_Password()
243+
{
244+
// just bom check
245+
Assert.That(Encoding.UTF8.GetBytes("я").Length, Is.EqualTo(2));
246+
var data = Encoding.UTF8.GetBytes("some compressible not very long string. some some some.");
247+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
248+
blazerCompressionOptions.SetEncoderByAlgorithm(BlazerAlgorithm.Stream);
249+
blazerCompressionOptions.PasswordRaw = new[] { (byte)'a', (byte)'b', (byte)'c' };
250+
blazerCompressionOptions.FlushMode = BlazerFlushMode.AutoFlush;
251+
IntegrityHelper.CheckCompressDecompress(data, blazerCompressionOptions, s => new BlazerOutputStream(s, new BlazerDecompressionOptions("abc")));
252+
}
230253
}
231254
}

Blazer.Net.Tests/OptionsTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,27 @@ public void Comment_Should_Be_Stored()
196196
Assert.That(os.Comment, Is.EqualTo("Test Comment Юникоде"));
197197
}
198198

199+
[Test]
200+
public void CommentRaw_Should_Be_Stored()
201+
{
202+
var data = new byte[123];
203+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
204+
blazerCompressionOptions.CommentRaw = new byte[] { 1, 2, 3 };
205+
// with footer
206+
var compressed = IntegrityHelper.CompressData(data, blazerCompressionOptions);
207+
var os = new BlazerOutputStream(new MemoryStream(compressed));
208+
CollectionAssert.AreEqual(new byte[] { 1, 2, 3 }, os.CommentRaw);
209+
}
210+
211+
[Test]
212+
public void CommentRaw_Should_Relate_Comment()
213+
{
214+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
215+
blazerCompressionOptions.Comment = "abc";
216+
Assert.That(blazerCompressionOptions.CommentRaw.Length, Is.EqualTo(3));
217+
Assert.That(blazerCompressionOptions.CommentRaw[0], Is.EqualTo((int)'a'));
218+
}
219+
199220
[Test]
200221
public void NoSeek_Should_Be_Respected()
201222
{

Blazer.Net/Algorithms/BufferInfo.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,12 @@ public BufferInfo(byte[] buffer, int offset, int length)
4040
Offset = offset;
4141
Length = length;
4242
}
43+
44+
public byte[] ExtractToSeparateArray()
45+
{
46+
var res = new byte[Length];
47+
System.Buffer.BlockCopy(Buffer, Offset, res, 0, Count);
48+
return res;
49+
}
4350
}
4451
}

Blazer.Net/BlazerCompressionOptions.cs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Text;
23

34
using Force.Blazer.Algorithms;
45

@@ -19,7 +20,23 @@ public class BlazerCompressionOptions
1920
/// <summary>
2021
/// Password for encrypting data
2122
/// </summary>
22-
public string Password { get; set; }
23+
public string Password
24+
{
25+
get
26+
{
27+
return PasswordRaw == null ? null : Encoding.UTF8.GetString(PasswordRaw);
28+
}
29+
30+
set
31+
{
32+
PasswordRaw = string.IsNullOrEmpty(value) ? null : Encoding.UTF8.GetBytes(value);
33+
}
34+
}
35+
36+
/// <summary>
37+
/// Password for encrypting data (raw binary variant)
38+
/// </summary>
39+
public byte[] PasswordRaw { get; set; }
2340

2441
/// <summary>
2542
/// Encrypt full flag. Fully encypted streams does not reveal any information about inner data (blazer header is also encypted)
@@ -208,7 +225,7 @@ public static BlazerCompressionOptions CreateBlock()
208225
public BlazerFlags GetFlags()
209226
{
210227
var flags = _flags;
211-
if (!string.IsNullOrEmpty(Password))
228+
if (PasswordRaw != null && PasswordRaw.Length != 0)
212229
{
213230
flags |= EncryptFull ? BlazerFlags.EncryptOuter : BlazerFlags.EncryptInner;
214231
}
@@ -240,7 +257,7 @@ public void SetEncoderByAlgorithm(BlazerAlgorithm algorithm)
240257

241258
private BlazerFileInfo _fileInfo;
242259

243-
private string _comment;
260+
private byte[] _commentRaw;
244261

245262
/// <summary>
246263
/// Gets or sets information about encoded file
@@ -286,13 +303,29 @@ public string Comment
286303
{
287304
get
288305
{
289-
return _comment;
306+
return CommentRaw == null ? null : Encoding.UTF8.GetString(CommentRaw);
307+
}
308+
309+
set
310+
{
311+
CommentRaw = value == null ? null : Encoding.UTF8.GetBytes(value);
312+
}
313+
}
314+
315+
/// <summary>
316+
/// Gets or sets archive raw (binary) comment. Useful for adding some info for technical streams
317+
/// </summary>
318+
public byte[] CommentRaw
319+
{
320+
get
321+
{
322+
return _commentRaw;
290323
}
291324

292325
set
293326
{
294-
_comment = value;
295-
SetFlag(BlazerFlags.IncludeComment, !string.IsNullOrEmpty(value));
327+
_commentRaw = value;
328+
SetFlag(BlazerFlags.IncludeComment, value != null && value.Length > 0);
296329
}
297330
}
298331
}

Blazer.Net/BlazerDecompressionOptions.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Text;
23

34
using Force.Blazer.Algorithms;
45

@@ -33,9 +34,25 @@ public void SetDecoderByAlgorithm(BlazerAlgorithm algorithm)
3334
public bool LeaveStreamOpen { get; set; }
3435

3536
/// <summary>
36-
/// Password for decrypting data
37+
/// Password for encrypting data
3738
/// </summary>
38-
public string Password { get; set; }
39+
public string Password
40+
{
41+
get
42+
{
43+
return PasswordRaw == null ? null : Encoding.UTF8.GetString(PasswordRaw);
44+
}
45+
46+
set
47+
{
48+
PasswordRaw = string.IsNullOrEmpty(value) ? null : Encoding.UTF8.GetBytes(value);
49+
}
50+
}
51+
52+
/// <summary>
53+
/// Password for decrypting data (raw binary variant)
54+
/// </summary>
55+
public byte[] PasswordRaw { get; set; }
3956

4057
/// <summary>
4158
/// Encrypt full flag. Fully encypted streams does not reveal any information about inner data (blazer header is also encypted)
@@ -85,5 +102,13 @@ public BlazerDecompressionOptions(string password)
85102
{
86103
Password = password;
87104
}
105+
106+
/// <summary>
107+
/// Constructor for default options with raw password
108+
/// </summary>
109+
public BlazerDecompressionOptions(byte[] passwordRaw)
110+
{
111+
PasswordRaw = passwordRaw;
112+
}
88113
}
89114
}

Blazer.Net/BlazerInputStream.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.IO;
3-
using System.Text;
43

54
using Force.Blazer.Algorithms;
65
using Force.Blazer.Algorithms.Crc32C;
@@ -155,9 +154,9 @@ public BlazerInputStream(Stream innerStream, BlazerCompressionOptions options)
155154
var encyptOuter = (flags & BlazerFlags.EncryptOuter) != 0;
156155
if (encyptOuter)
157156
{
158-
if (string.IsNullOrEmpty(options.Password))
157+
if (options.PasswordRaw == null || options.PasswordRaw.Length == 0)
159158
throw new InvalidOperationException("Encryption flag was set, but password is missing.");
160-
_innerStream = EncryptHelper.ConvertStreamToEncyptionStream(innerStream, options.Password);
159+
_innerStream = EncryptHelper.ConvertStreamToEncyptionStream(innerStream, options.PasswordRaw);
161160
}
162161

163162
_leaveStreamOpen = options.LeaveStreamOpen;
@@ -175,10 +174,10 @@ public BlazerInputStream(Stream innerStream, BlazerCompressionOptions options)
175174
if (_encoderAlgorithmId > 15)
176175
throw new InvalidOperationException("Invalid encoder algorithm");
177176

178-
if (!string.IsNullOrEmpty(options.Password) && !encyptOuter)
177+
if (options.PasswordRaw != null && options.PasswordRaw.Length > 0 && !encyptOuter)
179178
{
180179
flags |= BlazerFlags.EncryptInner;
181-
_encryptHelper = new EncryptHelper(options.Password, _maxInBlockSize);
180+
_encryptHelper = new EncryptHelper(options.PasswordRaw, _maxInBlockSize);
182181
}
183182
else
184183
{
@@ -210,9 +209,9 @@ public BlazerInputStream(Stream innerStream, BlazerCompressionOptions options)
210209

211210
_isMultipleFiles = (flags & BlazerFlags.MultipleFiles) != 0;
212211

213-
if (!string.IsNullOrEmpty(options.Comment))
212+
if (options.CommentRaw != null && options.CommentRaw.Length > 0)
214213
{
215-
_commentHeader = Encoding.UTF8.GetBytes(options.Comment);
214+
_commentHeader = options.CommentRaw;
216215
if (_commentHeader.Length > 16 * 1048576)
217216
throw new InvalidOperationException("Invalid archive comment");
218217
}

Blazer.Net/BlazerOutputStream.cs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public override long Position
140140

141141
private readonly bool _noSeek;
142142

143-
private string _comment;
143+
private byte[] _commentRaw;
144144

145145
private NullDecryptHelper _decryptHelper;
146146

@@ -197,7 +197,18 @@ public string Comment
197197
{
198198
get
199199
{
200-
return _comment;
200+
return _commentRaw == null ? null : Encoding.UTF8.GetString(_commentRaw);
201+
}
202+
}
203+
204+
/// <summary>
205+
/// Archive raw comment (binary)
206+
/// </summary>
207+
public byte[] CommentRaw
208+
{
209+
get
210+
{
211+
return _commentRaw;
201212
}
202213
}
203214

@@ -220,17 +231,17 @@ public BlazerOutputStream(Stream innerStream, BlazerDecompressionOptions options
220231
if (!_innerStream.CanRead)
221232
throw new InvalidOperationException("Base stream is invalid");
222233

223-
var password = options.Password;
234+
var password = options.PasswordRaw;
224235
_controlDataCallback = options.ControlDataCallback ?? ((b, o, c) => { });
225236
_fileInfoCallback = options.FileInfoCallback ?? (f => { });
226237
_doNotFireInfoCallbackOnOneFile = options.DoNotFireInfoCallbackOnOneFile;
227238
_noSeek = options.NoSeek;
228239

229240
if (options.EncyptFull)
230241
{
231-
if (string.IsNullOrEmpty(options.Password))
242+
if (options.Password == null || options.Password.Length == 0)
232243
throw new InvalidOperationException("Encryption flag was set, but password is missing.");
233-
_innerStream = DecryptHelper.ConvertStreamToDecyptionStream(innerStream, options.Password);
244+
_innerStream = DecryptHelper.ConvertStreamToDecyptionStream(innerStream, options.PasswordRaw);
234245
// no more password for this
235246
password = null;
236247
}
@@ -254,7 +265,7 @@ public BlazerOutputStream(Stream innerStream, BlazerDecompressionOptions options
254265
}
255266
}
256267

257-
private void InitByFlags(BlazerFlags flags, IDecoder decoder, string password)
268+
private void InitByFlags(BlazerFlags flags, IDecoder decoder, byte[] password)
258269
{
259270
if ((flags & BlazerFlags.IncludeHeader) != 0)
260271
throw new InvalidOperationException("Flags cannot contains IncludeHeader flags");
@@ -271,7 +282,7 @@ private void InitByFlags(BlazerFlags flags, IDecoder decoder, string password)
271282
_haveMultipleFiles = (flags & BlazerFlags.MultipleFiles) != 0;
272283
_shouldHaveComment = (flags & BlazerFlags.IncludeComment) != 0;
273284

274-
if (!string.IsNullOrEmpty(password))
285+
if (!(password == null || password.Length == 0))
275286
{
276287
_decryptHelper = new DecryptHelper(password);
277288
var encHeader = new byte[_decryptHelper.GetHeaderLength()];
@@ -289,9 +300,9 @@ private void InitByFlags(BlazerFlags flags, IDecoder decoder, string password)
289300
ReadCommonBlocks();
290301
}
291302

292-
private void InitByHeader(string password = null)
303+
private void InitByHeader(byte[] password = null)
293304
{
294-
_decryptHelper = string.IsNullOrEmpty(password) ? new NullDecryptHelper() : new DecryptHelper(password);
305+
_decryptHelper = password == null || password.Length == 0 ? new NullDecryptHelper() : new DecryptHelper(password);
295306

296307
ReadAndValidateHeader();
297308

@@ -305,7 +316,7 @@ private void ReadCommonBlocks()
305316
var commentBytes = GetNextChunk(true);
306317
if (_encodingType != (byte)BlazerBlockType.Comment)
307318
throw new InvalidOperationException("Invalid comment header");
308-
_comment = Encoding.UTF8.GetString(commentBytes.Buffer, commentBytes.Offset, commentBytes.Count);
319+
_commentRaw = commentBytes.ExtractToSeparateArray();
309320
}
310321

311322
// todo: refactor this

Blazer.Net/Encyption/DecryptHelper.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using System.Security.Cryptography;
6-
using System.Threading;
6+
using System.Text;
77

88
using Force.Blazer.Algorithms;
99

@@ -38,13 +38,18 @@ internal class DecryptHelper : NullDecryptHelper
3838

3939
private Aes _aes;
4040

41-
private string _password;
41+
private byte[] _passwordRaw;
4242

4343
private byte[] _buffer;
4444

4545
public DecryptHelper(string password)
4646
{
47-
_password = password;
47+
_passwordRaw = string.IsNullOrEmpty(password) ? null : Encoding.UTF8.GetBytes(password);
48+
}
49+
50+
public DecryptHelper(byte[] passwordRaw)
51+
{
52+
_passwordRaw = passwordRaw;
4853
}
4954

5055
public override int GetHeaderLength()
@@ -65,8 +70,8 @@ public override void Init(byte[] buffer, int maxBlockSize)
6570

6671
var salt = new byte[8];
6772
Buffer.BlockCopy(buffer, 0, salt, 0, 8);
68-
var pass = new Rfc2898DeriveBytes(_password, salt, PbkIterations);
69-
_password = null;
73+
var pass = new Rfc2898DeriveBytes(_passwordRaw, salt, PbkIterations);
74+
_passwordRaw = null;
7075
_aes = Aes.Create();
7176
_aes.Key = pass.GetBytes(32);
7277
// zero. it is ok
@@ -125,7 +130,7 @@ public override int AdjustLength(int inLength)
125130
return ((inLength - 1 + 8) | 15) + 1;
126131
}
127132

128-
public static Stream ConvertStreamToDecyptionStream(Stream inner, string password)
133+
public static Stream ConvertStreamToDecyptionStream(Stream inner, byte[] password)
129134
{
130135
var salt = new byte[8];
131136
// ensure read 8 bytes

0 commit comments

Comments
 (0)