public async Task <Stream> DecryptInternal(
            Stream content,
            Metadata metadata,
            HttpRange originalRange,
            string receivedContentRange,
            bool async,
            CancellationToken cancellationToken)
        {
            ContentRange?contentRange = string.IsNullOrWhiteSpace(receivedContentRange)
                ? default
                : ContentRange.Parse(receivedContentRange);

            EncryptionData encryptionData = GetAndValidateEncryptionDataOrDefault(metadata);

            if (encryptionData == default)
            {
                return(await TrimStreamInternal(content, originalRange, contentRange, pulledOutIV : false, async, cancellationToken).ConfigureAwait(false));
            }

            bool ivInStream = originalRange.Offset >= Constants.ClientSideEncryption.EncryptionBlockSize;

            // this method throws when key cannot be resolved. Blobs is intended to throw on this failure.
            var plaintext = await _decryptor.DecryptInternal(
                content,
                encryptionData,
                ivInStream,
                CanIgnorePadding(contentRange),
                async,
                cancellationToken).ConfigureAwait(false);

            return(await TrimStreamInternal(plaintext, originalRange, contentRange, ivInStream, async, cancellationToken).ConfigureAwait(false));
        }
Esempio n. 2
0
        public async Task <Stream> DecryptInternal(
            Stream content,
            Metadata metadata,
            HttpRange originalRange,
            string receivedContentRange,
            bool async,
            CancellationToken cancellationToken)
        {
            ContentRange?contentRange = string.IsNullOrWhiteSpace(receivedContentRange)
                ? default
                : ContentRange.Parse(receivedContentRange);

            EncryptionData encryptionData = GetAndValidateEncryptionDataOrDefault(metadata);

            if (encryptionData == default)
            {
                return(await TrimStreamInternal(content, originalRange, contentRange, alreadyTrimmedOffsetAmount : 0, async, cancellationToken).ConfigureAwait(false));
            }

            bool ivInStream = originalRange.Offset >= Constants.ClientSideEncryption.EncryptionBlockSize;

            // this method throws when key cannot be resolved. Blobs is intended to throw on this failure.
            var plaintext = await _decryptor.DecryptReadInternal(
                content,
                encryptionData,
                ivInStream,
                CanIgnorePadding(contentRange),
                async,
                cancellationToken).ConfigureAwait(false);

            int v2StartRegion0Indexed = (int)((contentRange?.Start / encryptionData.EncryptedRegionInfo?.GetTotalRegionLength()) ?? 0);
            int alreadyTrimmedOffset  = encryptionData.EncryptionAgent.EncryptionVersion switch
            {
                ClientSideEncryptionVersion.V1_0 => ivInStream ? Constants.ClientSideEncryption.EncryptionBlockSize : 0,
                // first block is special case where we don't want to communicate a trim. Otherwise communicate nonce length * 1-indexed start region + tag length * 0-indexed region
                ClientSideEncryptionVersion.V2_0 => contentRange?.Start > 0
                    ? (-encryptionData.EncryptedRegionInfo.NonceLength * (v2StartRegion0Indexed)) - (Constants.ClientSideEncryption.V2.TagSize * v2StartRegion0Indexed)
                    : 0,
                _ => throw Errors.ClientSideEncryption.ClientSideEncryptionVersionNotSupported()
            };

            return(await TrimStreamInternal(plaintext, originalRange, contentRange, alreadyTrimmedOffset, async, cancellationToken).ConfigureAwait(false));
        }