1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

Made sure all encryption methods were properly disposed

This commit is contained in:
Uncled1023 2022-05-22 18:52:04 -07:00
parent 9fbed1aed0
commit 1454fd9317
3 changed files with 49 additions and 40 deletions

View File

@ -154,7 +154,10 @@
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<div class="btn-group pull-right" role="group"> <div class="btn-group pull-right" role="group">
@if (User.Identity.IsAuthenticated)
{
<button type="button" class="btn btn-default btn-sm" id="shortenUrl"><i class="fa fa-link"></i>&nbsp;Shorten</button> <button type="button" class="btn btn-default btn-sm" id="shortenUrl"><i class="fa fa-link"></i>&nbsp;Shorten</button>
}
<button type="button" class="btn btn-default btn-sm" id="delete-link"><i class="fa fa-trash"></i>&nbsp;Deletion Link</button> <button type="button" class="btn btn-default btn-sm" id="delete-link"><i class="fa fa-trash"></i>&nbsp;Deletion Link</button>
</div> </div>
</div> </div>

View File

@ -7,17 +7,17 @@ namespace Teknik.Utilities.Cryptography
{ {
// Internal Variables // Internal Variables
private const int _BlockSize = 16; private const int _BlockSize = 16;
private readonly byte[] _Counter; private readonly byte[] _InitialCounter;
private readonly AesManaged _Algo; private readonly AesManaged _Algo;
public AesCounterMode() : this(new byte[_BlockSize]) { } public AesCounterMode() : this(new byte[_BlockSize]) { }
public AesCounterMode(byte[] counter) public AesCounterMode(byte[] initialCounter)
{ {
if (counter == null) throw new ArgumentNullException("counter"); if (initialCounter == null) throw new ArgumentNullException("counter");
if (counter.Length != _BlockSize) if (initialCounter.Length != _BlockSize)
throw new ArgumentException(String.Format("Counter size must be same as block size (actual: {0}, expected: {1})", throw new ArgumentException(String.Format("Counter size must be same as block size (actual: {0}, expected: {1})",
counter.Length, _BlockSize)); initialCounter.Length, _BlockSize));
// Generate a new instance of the Aes Algorithm in ECB mode with no padding // Generate a new instance of the Aes Algorithm in ECB mode with no padding
_Algo = new AesManaged _Algo = new AesManaged
@ -27,18 +27,17 @@ namespace Teknik.Utilities.Cryptography
}; };
// Set the internal variables // Set the internal variables
_Counter = new byte[counter.Length]; _InitialCounter = initialCounter;
counter.CopyTo(_Counter, 0);
} }
public override ICryptoTransform CreateEncryptor(byte[] key, byte[] iv) public override ICryptoTransform CreateEncryptor(byte[] key, byte[] iv)
{ {
return new CounterModeCryptoTransform(_Algo, key, iv, _Counter); return new CounterModeCryptoTransform(_Algo, key, iv, _InitialCounter);
} }
public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv) public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv)
{ {
return new CounterModeCryptoTransform(_Algo, key, iv, _Counter); return new CounterModeCryptoTransform(_Algo, key, iv, _InitialCounter);
} }
public override void GenerateKey() public override void GenerateKey()
@ -50,17 +49,22 @@ namespace Teknik.Utilities.Cryptography
{ {
_Algo.GenerateIV(); _Algo.GenerateIV();
} }
protected override void Dispose(bool disposed)
{
_Algo.Dispose();
}
} }
public class CounterModeCryptoTransform : ICryptoTransform public class CounterModeCryptoTransform : ICryptoTransform
{ {
private readonly byte[] _IV; private readonly int _BlockSize;
private readonly Memory<byte> _IV;
private readonly byte[] _Counter; private readonly byte[] _Counter;
private readonly byte[] _EncryptedCounter;
private readonly ICryptoTransform _CounterEncryptor; private readonly ICryptoTransform _CounterEncryptor;
private readonly SymmetricAlgorithm _SymmetricAlgorithm;
// Stateful Fields // Stateful Fields
private byte[] _EncryptedCounter;
private int _Iterations; private int _Iterations;
public int Iterations public int Iterations
@ -87,28 +91,26 @@ namespace Teknik.Utilities.Cryptography
} }
} }
public CounterModeCryptoTransform(SymmetricAlgorithm symmetricAlgorithm, byte[] key, byte[] iv, byte[] counter) public CounterModeCryptoTransform(SymmetricAlgorithm symmetricAlgorithm, byte[] key, byte[] iv, byte[] initialCounter)
{ {
if (symmetricAlgorithm == null) throw new ArgumentNullException("symmetricAlgorithm"); if (symmetricAlgorithm == null) throw new ArgumentNullException("symmetricAlgorithm");
if (key == null) throw new ArgumentNullException("key"); if (key == null) throw new ArgumentNullException("key");
if (iv == null) throw new ArgumentNullException("iv"); if (iv == null) throw new ArgumentNullException("iv");
if (counter == null) throw new ArgumentNullException("counter"); if (initialCounter == null) throw new ArgumentNullException("counter");
// Check lengths // Check lengths
if (counter.Length != symmetricAlgorithm.BlockSize / 8) if (initialCounter.Length != symmetricAlgorithm.BlockSize / 8)
throw new ArgumentException(String.Format("Counter size must be same as block size (actual: {0}, expected: {1})", throw new ArgumentException(String.Format("Counter size must be same as block size (actual: {0}, expected: {1})",
counter.Length, symmetricAlgorithm.BlockSize / 8)); initialCounter.Length, symmetricAlgorithm.BlockSize / 8));
_SymmetricAlgorithm = symmetricAlgorithm; _BlockSize = symmetricAlgorithm.BlockSize;
// Initialize the encrypted counter // Initialize the encrypted counter
_EncryptedCounter = new byte[_SymmetricAlgorithm.BlockSize / 8]; _EncryptedCounter = new byte[_BlockSize / 8];
_IV = new byte[iv.Length]; _IV = iv;
iv.CopyTo(_IV, 0);
_Counter = new byte[counter.Length]; _Counter = initialCounter;
counter.CopyTo(_Counter, 0);
_CounterEncryptor = symmetricAlgorithm.CreateEncryptor(key, iv); _CounterEncryptor = symmetricAlgorithm.CreateEncryptor(key, iv);
@ -163,6 +165,13 @@ namespace Teknik.Utilities.Cryptography
} }
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
ReadOnlySpan<byte> input = inputBuffer;
Span<byte> output = outputBuffer;
return TransformBlock(input, inputOffset, inputCount, output, outputOffset);
}
public int TransformBlock(ReadOnlySpan<byte> inputBuffer, int inputOffset, int inputCount, Span<byte> outputBuffer, int outputOffset)
{ {
for (var i = 0; i < inputCount; i++) for (var i = 0; i < inputCount; i++)
{ {
@ -191,17 +200,13 @@ namespace Teknik.Utilities.Cryptography
public void EncryptCounter() public void EncryptCounter()
{ {
// Clear the encrypted counter
Array.Clear(_EncryptedCounter, 0, _EncryptedCounter.Length);
// Encrypt the current counter to the encrypted counter // Encrypt the current counter to the encrypted counter
_CounterEncryptor.TransformBlock(_Counter, 0, _Counter.Length, _EncryptedCounter, 0); _CounterEncryptor.TransformBlock(_Counter, 0, _Counter.Length, _EncryptedCounter, 0);
} }
public void ResetCounter() public void ResetCounter()
{ {
Array.Clear(_Counter, 0, _Counter.Length); _IV.CopyTo(_Counter);
_IV.CopyTo(_Counter, 0);
_Iterations = 0; _Iterations = 0;
} }
@ -214,13 +219,14 @@ namespace Teknik.Utilities.Cryptography
_Iterations++; _Iterations++;
} }
public int InputBlockSize { get { return _SymmetricAlgorithm.BlockSize / 8; } } public int InputBlockSize { get { return _BlockSize / 8; } }
public int OutputBlockSize { get { return _SymmetricAlgorithm.BlockSize / 8; } } public int OutputBlockSize { get { return _BlockSize / 8; } }
public bool CanTransformMultipleBlocks { get { return true; } } public bool CanTransformMultipleBlocks { get { return true; } }
public bool CanReuseTransform { get { return false; } } public bool CanReuseTransform { get { return false; } }
public void Dispose() public void Dispose()
{ {
_CounterEncryptor.Dispose();
} }
} }
} }

View File

@ -24,7 +24,7 @@ namespace Teknik.Utilities.Cryptography
_Inner = stream; _Inner = stream;
// Create the Aes Cipher // Create the Aes Cipher
AesCounterMode aes = new AesCounterMode(iv); using AesCounterMode aes = new AesCounterMode(iv);
if (encrypt) if (encrypt)
{ {
_Cipher = (CounterModeCryptoTransform)aes.CreateEncryptor(key, iv); // Encrypt _Cipher = (CounterModeCryptoTransform)aes.CreateEncryptor(key, iv); // Encrypt
@ -70,22 +70,22 @@ namespace Teknik.Utilities.Cryptography
{ {
if (_Inner != null && CanRead) if (_Inner != null && CanRead)
{ {
Memory<byte> readBuf = buffer; Span<byte> readBuf = buffer;
int processed = 0; int processed = 0;
// Read the data from the stream // Read the data from the stream
int bytesRead = _Inner.Read(readBuf.Span.Slice(offset, count)); int bytesRead = _Inner.Read(readBuf.Slice(offset, count));
if (bytesRead > 0) if (bytesRead > 0)
{ {
// Process the read buffer // Process the read buffer
processed = _Cipher.TransformBlock(readBuf.Span, offset, bytesRead); processed = _Cipher.TransformBlock(readBuf, offset, bytesRead);
} }
// Do we have more? // Do we have more?
if (processed < bytesRead) if (processed < bytesRead)
{ {
// Finalize the cipher // Finalize the cipher
var finalProcessed = _Cipher.TransformFinalBlock(readBuf.Span, processed + offset, bytesRead); var finalProcessed = _Cipher.TransformFinalBlock(readBuf, processed + offset, bytesRead);
if (finalProcessed > 0) if (finalProcessed > 0)
processed += finalProcessed; processed += finalProcessed;
} }
@ -249,16 +249,16 @@ namespace Teknik.Utilities.Cryptography
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
_Cipher.Dispose();
_Inner.Dispose(); _Inner.Dispose();
base.Dispose(disposing); base.Dispose(disposing);
} }
public override ValueTask DisposeAsync() public override async ValueTask DisposeAsync()
{ {
_Inner.DisposeAsync(); await _Inner.DisposeAsync();
await base.DisposeAsync();
return base.DisposeAsync();
} }
private void SyncCounter() private void SyncCounter()