BlobClientSideDecryptor
class BlobClientSideDecryptor
using Azure.Storage.Common;
using Azure.Storage.Cryptography;
using Azure.Storage.Cryptography.Models;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace Azure.Storage.Blobs
{
internal class BlobClientSideDecryptor
{
private readonly ClientSideDecryptor _decryptor;
public BlobClientSideDecryptor(ClientSideDecryptor decryptor)
{
_decryptor = decryptor;
}
[AsyncStateMachine(typeof(<DecryptInternal>d__2))]
public Task<Stream> DecryptInternal(Stream content, IDictionary<string, string> metadata, HttpRange originalRange, string receivedContentRange, bool async, CancellationToken cancellationToken)
{
<DecryptInternal>d__2 stateMachine = default(<DecryptInternal>d__2);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<Stream>.Create();
stateMachine.<>4__this = this;
stateMachine.content = content;
stateMachine.metadata = metadata;
stateMachine.originalRange = originalRange;
stateMachine.receivedContentRange = receivedContentRange;
stateMachine.async = async;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<DecryptWholeBlobWriteInternal>d__3))]
public Task<Stream> DecryptWholeBlobWriteInternal(Stream plaintextDestination, IDictionary<string, string> metadata, bool async, CancellationToken cancellationToken)
{
<DecryptWholeBlobWriteInternal>d__3 stateMachine = default(<DecryptWholeBlobWriteInternal>d__3);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<Stream>.Create();
stateMachine.<>4__this = this;
stateMachine.plaintextDestination = plaintextDestination;
stateMachine.metadata = metadata;
stateMachine.async = async;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<TrimStreamInternal>d__4))]
private static Task<Stream> TrimStreamInternal(Stream stream, HttpRange originalRange, ContentRange? receivedRange, int alreadyTrimmedOffsetAmount, bool async, CancellationToken cancellationToken)
{
<TrimStreamInternal>d__4 stateMachine = default(<TrimStreamInternal>d__4);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<Stream>.Create();
stateMachine.stream = stream;
stateMachine.originalRange = originalRange;
stateMachine.receivedRange = receivedRange;
stateMachine.alreadyTrimmedOffsetAmount = alreadyTrimmedOffsetAmount;
stateMachine.async = async;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
internal static EncryptionData GetAndValidateEncryptionDataOrDefault(IDictionary<string, string> metadata)
{
if (metadata == null)
return null;
if (!metadata.TryGetValue("encryptiondata", out string value))
return null;
EncryptionData encryptionData = EncryptionDataSerializer.Deserialize(value);
switch (encryptionData.EncryptionAgent.EncryptionVersion) {
case ClientSideEncryptionVersionInternal.V1_0:
if (encryptionData.ContentEncryptionIV == null)
throw Errors.ClientSideEncryption.MissingEncryptionMetadata("ContentEncryptionIV");
break;
case ClientSideEncryptionVersionInternal.V2_0:
case ClientSideEncryptionVersionInternal.V2_1:
if (encryptionData.EncryptedRegionInfo == null)
throw Errors.ClientSideEncryption.MissingEncryptionMetadata("EncryptedRegionInfo");
break;
default:
throw Errors.ClientSideEncryption.ClientSideEncryptionVersionNotSupported(null);
}
if (encryptionData.WrappedContentKey.EncryptedKey == null)
throw Errors.ClientSideEncryption.MissingEncryptionMetadata("EncryptedKey");
return encryptionData;
}
private static bool CanIgnorePadding(ContentRange? contentRange)
{
if (!contentRange.HasValue)
return false;
ContentRange value = contentRange.Value;
if (!value.End.HasValue)
return false;
value = contentRange.Value;
long? size = value.Size;
value = contentRange.Value;
long? nullable = size - value.End;
long num = 1;
if ((nullable.GetValueOrDefault() == num) & nullable.HasValue)
return false;
return true;
}
internal static HttpRange GetEncryptedBlobRange(HttpRange originalRange, string rawEncryptionData)
{
Argument.AssertNotNull(rawEncryptionData, "rawEncryptionData");
EncryptionData encryptionData = EncryptionDataSerializer.Deserialize(rawEncryptionData);
return GetEncryptedBlobRange(originalRange, encryptionData);
}
internal static HttpRange GetEncryptedBlobRange(HttpRange originalRange, EncryptionData encryptionData)
{
if (encryptionData != null) {
switch (encryptionData.EncryptionAgent.EncryptionVersion) {
case ClientSideEncryptionVersionInternal.V1_0:
return GetEncryptedBlobRangeV1_0(originalRange);
case ClientSideEncryptionVersionInternal.V2_0:
case ClientSideEncryptionVersionInternal.V2_1:
return GetEncryptedBlobRangeV2_0(originalRange, encryptionData);
default:
throw Errors.InvalidArgument("encryptionData");
}
}
return originalRange;
}
private static HttpRange GetEncryptedBlobRangeV2_0(HttpRange originalRange, EncryptionData encryptionData)
{
int dataLength = encryptionData.EncryptedRegionInfo.DataLength;
int num = encryptionData.EncryptedRegionInfo.NonceLength + encryptionData.EncryptedRegionInfo.DataLength + 16;
long num2 = 0;
long? nullable = null;
if (originalRange.get_Offset() != 0)
num2 = originalRange.get_Offset() / dataLength * num;
if (originalRange.get_Length().HasValue) {
long num3 = (originalRange.get_Offset() + originalRange.get_Length().Value - 1) / dataLength;
nullable = (num3 + 1) * num - num2;
}
return new HttpRange(num2, nullable);
}
private static HttpRange GetEncryptedBlobRangeV1_0(HttpRange originalRange)
{
int num = 0;
long? nullable = originalRange.get_Length();
if (originalRange.get_Offset() != 0) {
int num2;
if ((num2 = (int)(originalRange.get_Offset() % 16)) != 0) {
num += num2;
if (nullable.HasValue)
nullable += num2;
}
if (originalRange.get_Offset() >= 16) {
num += 16;
if (nullable.HasValue)
nullable += 16;
}
}
if (nullable.HasValue)
nullable += (16 - (int)(nullable % 16).Value) % 16;
return new HttpRange(originalRange.get_Offset() - num, nullable);
}
}
}