/// <summary> /// Internal helper method to wrap a user provided stream with the appropriate crypto stream. /// </summary> internal static Stream WrapUserStreamWithDecryptStream(CloudBlob blob, Stream userProvidedStream, BlobRequestOptions options, BlobAttributes attributes, bool rangeRead, out ICryptoTransform transform, long?endOffset = null, long?userSpecifiedLength = null, int discardFirst = 0, bool bufferIV = false) { if (!rangeRead) { // The user provided stream should be wrapped in a NonCloseableStream in order to // avoid closing the user stream when the crypto stream is closed to flush the final decrypted // block of data. Stream decryptStream = options.EncryptionPolicy.DecryptBlob(new NonCloseableStream(userProvidedStream), attributes.Metadata, out transform, options.RequireEncryption, null, blob.BlobType == BlobType.PageBlob); return(decryptStream); } else { // Check if end offset lies in the last AES block and send this information over to set the correct padding mode. bool noPadding = blob.BlobType == BlobType.PageBlob || (endOffset.HasValue && endOffset.Value < attributes.Properties.Length - 16); transform = null; return(new BlobDecryptStream(userProvidedStream, attributes.Metadata, userSpecifiedLength, discardFirst, bufferIV, noPadding, options.EncryptionPolicy, options.RequireEncryption)); } }
/// <summary> /// Initializes a new instance of the <see cref="CloudBlockBlob"/> class. /// </summary> /// <param name="attributes">The attributes.</param> /// <param name="serviceClient">The service client.</param> internal CloudBlockBlob(BlobAttributes attributes, CloudBlobClient serviceClient) : base(attributes, serviceClient) { this.Properties.BlobType = BlobType.BlockBlob; }