AuthenticatedRegionCryptoStream
using Azure.Core.Pipeline;
using Azure.Storage.Cryptography.Models;
using System;
using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
namespace Azure.Storage.Cryptography
{
internal class AuthenticatedRegionCryptoStream : Stream
{
private readonly Stream _innerStream;
private readonly CryptoStreamMode _mode;
private readonly IAuthenticatedCryptographicTransform _transform;
private bool _flushedFinal;
private readonly byte[] _buffer;
private int _bufferPos;
private int _bufferPopulatedLength;
private readonly int _bufferLength;
private readonly int _tempRefillBufferSize;
public override bool CanRead => _mode == CryptoStreamMode.Read;
public override bool CanWrite {
get {
if (_mode == CryptoStreamMode.Write)
return !_flushedFinal;
return false;
}
}
public override bool CanSeek => false;
public override long Length {
get {
throw new NotSupportedException();
}
}
public override long Position {
get {
throw new NotSupportedException();
}
set {
throw new NotSupportedException();
}
}
public AuthenticatedRegionCryptoStream(Stream innerStream, IAuthenticatedCryptographicTransform transform, int regionDataSize, CryptoStreamMode streamMode)
{
_innerStream = innerStream;
_transform = transform;
_mode = streamMode;
int num;
if ((transform.TransformMode == TransformMode.Encrypt && streamMode == CryptoStreamMode.Write) || (transform.TransformMode == TransformMode.Decrypt && streamMode == CryptoStreamMode.Read)) {
num = regionDataSize;
_tempRefillBufferSize = transform.NonceLength + regionDataSize + transform.TagLength;
} else {
if ((transform.TransformMode != 0 || streamMode != 0) && (transform.TransformMode != TransformMode.Decrypt || streamMode != CryptoStreamMode.Write))
throw Errors.InvalidArgument("transform");
num = transform.NonceLength + regionDataSize + transform.TagLength;
_tempRefillBufferSize = regionDataSize;
}
_buffer = ArrayPool<byte>.Shared.Rent(num);
_bufferLength = num;
_bufferPopulatedLength = _bufferLength;
int bufferPos;
switch (streamMode) {
case CryptoStreamMode.Read:
bufferPos = _bufferLength;
break;
case CryptoStreamMode.Write:
bufferPos = 0;
break;
default:
throw Errors.InvalidArgument("streamMode");
}
_bufferPos = bufferPos;
}
public override int Read(byte[] buffer, int offset, int count)
{
return ReadInternal(buffer, offset, count, false, default(CancellationToken)).EnsureCompleted();
}
[AsyncStateMachine(typeof(<ReadAsync>d__22))]
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
<ReadAsync>d__22 stateMachine = default(<ReadAsync>d__22);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
stateMachine.<>4__this = this;
stateMachine.buffer = buffer;
stateMachine.offset = offset;
stateMachine.count = count;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<ReadInternal>d__23))]
private Task<int> ReadInternal(byte[] buffer, int offset, int count, bool async, CancellationToken cancellationToken)
{
<ReadInternal>d__23 stateMachine = default(<ReadInternal>d__23);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
stateMachine.<>4__this = this;
stateMachine.buffer = buffer;
stateMachine.offset = offset;
stateMachine.count = count;
stateMachine.async = async;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public override void Write(byte[] buffer, int offset, int count)
{
WriteInternal(buffer, offset, count, false, default(CancellationToken)).EnsureCompleted();
}
[AsyncStateMachine(typeof(<WriteAsync>d__25))]
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
<WriteAsync>d__25 stateMachine = default(<WriteAsync>d__25);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.buffer = buffer;
stateMachine.offset = offset;
stateMachine.count = count;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<WriteInternal>d__26))]
private Task WriteInternal(byte[] buffer, int offset, int count, bool async, CancellationToken cancellationToken)
{
<WriteInternal>d__26 stateMachine = default(<WriteInternal>d__26);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.buffer = buffer;
stateMachine.offset = offset;
stateMachine.count = count;
stateMachine.async = async;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public override void Flush()
{
if (FlushToInnerIfReady(false, default(CancellationToken)).EnsureCompleted())
_innerStream.Flush();
}
[AsyncStateMachine(typeof(<FlushAsync>d__28))]
public override Task FlushAsync(CancellationToken cancellationToken)
{
<FlushAsync>d__28 stateMachine = default(<FlushAsync>d__28);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<FlushToInnerIfReady>d__29))]
private Task<bool> FlushToInnerIfReady(bool async, CancellationToken cancellationToken)
{
<FlushToInnerIfReady>d__29 stateMachine = default(<FlushToInnerIfReady>d__29);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<bool>.Create();
stateMachine.<>4__this = this;
stateMachine.async = async;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<FlushFinalInternal>d__30))]
public Task FlushFinalInternal(bool async, CancellationToken cancellationToken)
{
<FlushFinalInternal>d__30 stateMachine = default(<FlushFinalInternal>d__30);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.async = async;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
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 (CanWrite)
FlushFinalInternal(false, default(CancellationToken)).EnsureCompleted();
ArrayPool<byte>.Shared.Return(_buffer, false);
base.Dispose(disposing);
_transform.Dispose();
_innerStream?.Dispose();
}
}
}