Beispiel #1
0
        /// <summary>
        /// Retrieve a new <c>MemoryStream</c> object with the contents unzipped and copied from the provided
        /// stream. The provided stream is optionally closed.
        /// </summary>
        /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks>
        /// <param name="data"></param>
        /// <param name="leaveStreamOpen"></param>
        /// <returns></returns>
        public async ValueTask <MemoryStream> CompressAsync(Stream inputStream, bool leaveStreamOpen = false)
        {
            Guard.AgainstNullOrEmpty(inputStream, nameof(inputStream));

            if (inputStream.Position == inputStream.Length)
            {
                inputStream.Seek(0, SeekOrigin.Begin);
            }

            var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider));

            using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true))
            {
                await inputStream
                .CopyToAsync(gzipStream)
                .ConfigureAwait(false);
            }
            if (!leaveStreamOpen)
            {
                inputStream.Close();
            }

            compressedStream.Seek(0, SeekOrigin.Begin);
            return(compressedStream);
        }
Beispiel #2
0
        public async ValueTask <ArraySegment <byte> > CompressAsync(ReadOnlyMemory <byte> inputData)
        {
            Guard.AgainstEmpty(inputData, nameof(inputData));

            var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider));

            using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true))
            {
                await gzipStream
                .WriteAsync(inputData)
                .ConfigureAwait(false);
            }

            if (compressedStream.TryGetBuffer(out var buffer))
            {
                return(buffer);
            }
            else
            {
                using (compressedStream) // dispose stream after allocation.
                {
                    return(compressedStream.ToArray());
                }
            }
        }
Beispiel #3
0
        public async ValueTask <ArraySegment <byte> > DecompressAsync(ReadOnlyMemory <byte> compressedData)
        {
            Guard.AgainstEmpty(compressedData, nameof(compressedData));

            using var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider), CompressionHelpers.GetGzipUncompressedLength(compressedData));
            using (var gzipStream = new GZipStream(compressedData.AsStream(), CompressionMode.Decompress, false))
            {
                await gzipStream
                .CopyToAsync(uncompressedStream)
                .ConfigureAwait(false);
            }

            if (uncompressedStream.TryGetBuffer(out var buffer))
            {
                return(buffer);
            }
            else
            {
                // dispose stream after allocation.
                using (uncompressedStream)
                {
                    return(uncompressedStream.ToArray());
                }
            }
        }
Beispiel #4
0
        public void Middleware_Input2 <TIn>(TIn input)
        {
            using var serializedStream = RecyclableManager.GetStream(nameof(RecyclableTransformer));
            _middleware.SerializationProvider.Serialize(serializedStream, input);

            using var compressedStream = _middleware.CompressionProvider.Compress(serializedStream, false);
            var encryptedStream = _middleware.EncryptionProvider.Encrypt(compressedStream, false);
        }
Beispiel #5
0
        public MemoryStream Encrypt(MemoryStream unencryptedStream, bool leaveStreamOpen = false)
        {
            Guard.AgainstNullOrEmpty(unencryptedStream, nameof(unencryptedStream));

            using var aes = new AesGcm(_key.Span);

            var length = (int)unencryptedStream.Length;

            (var buffer, var returnBuffer) = unencryptedStream.GetSafeBuffer(length);

            // Slicing Version
            // Rented arrays sizes are minimums, not guarantees.
            // Need to perform extra work managing slices to keep the byte sizes correct but the memory allocations are lower by 200%
            var encryptedBytes = _pool.Rent(length);
            var tag            = _pool.Rent(AesGcm.TagByteSizes.MaxSize);   // MaxSize = 16
            var nonce          = _pool.Rent(AesGcm.NonceByteSizes.MaxSize); // MaxSize = 12

            _rng.GetBytes(nonce, 0, AesGcm.NonceByteSizes.MaxSize);

            aes.Encrypt(
                nonce.AsSpan().Slice(0, AesGcm.NonceByteSizes.MaxSize),
                buffer.AsSpan().Slice(0, length),
                encryptedBytes.AsSpan().Slice(0, length),
                tag.AsSpan().Slice(0, AesGcm.TagByteSizes.MaxSize));

            // Prefix ciphertext with nonce and tag, since they are fixed length and it will simplify decryption.
            // Our pattern: Nonce Tag Cipher
            // Other patterns people use: Nonce Cipher Tag // couldn't find a solid source.
            var encryptedStream = RecyclableManager.GetStream(
                nameof(RecyclableAesGcmEncryptionProvider),
                AesGcm.NonceByteSizes.MaxSize + AesGcm.TagByteSizes.MaxSize + length);

            using (var binaryWriter = new BinaryWriter(encryptedStream, Encoding.UTF8, true))
            {
                binaryWriter.Write(nonce, 0, AesGcm.NonceByteSizes.MaxSize);
                binaryWriter.Write(tag, 0, AesGcm.TagByteSizes.MaxSize);
                binaryWriter.Write(encryptedBytes, 0, length);
            }

            if (returnBuffer)
            {
                _pool.Return(buffer.Array);
            }

            _pool.Return(encryptedBytes);
            _pool.Return(tag);
            _pool.Return(nonce);

            encryptedStream.Seek(0, SeekOrigin.Begin);

            if (!leaveStreamOpen)
            {
                unencryptedStream.Close();
            }

            return(encryptedStream);
        }
        /// <summary>
        /// Returns a new <c>MemoryStream</c> that has decompressed data inside.
        /// </summary>
        /// <param name="compressedStream"></param>
        /// <param name="leaveStreamOpen"></param>
        /// <returns>A <c>new MemoryStream</c>.</returns>
        public MemoryStream DecompressToStream(ReadOnlyMemory <byte> compressedData)
        {
            Guard.AgainstEmpty(compressedData, nameof(compressedData));

            var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableBrotliProvider));

            using (var brotliStream = new BrotliStream(compressedData.AsStream(), CompressionMode.Decompress, false))
            {
                brotliStream.CopyTo(uncompressedStream);
            }

            return(uncompressedStream);
        }
Beispiel #7
0
        /// <summary>
        /// Returns a new <c>MemoryStream</c> that has decompressed data inside.
        /// </summary>
        /// <param name="compressedStream"></param>
        /// <param name="leaveStreamOpen"></param>
        /// <returns>A <c>new MemoryStream</c>.</returns>
        public MemoryStream DecompressToStream(ReadOnlyMemory <byte> compressedData)
        {
            Guard.AgainstEmpty(compressedData, nameof(compressedData));

            var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider), CompressionHelpers.GetGzipUncompressedLength(compressedData));

            using (var gzipStream = new GZipStream(compressedData.AsStream(), CompressionMode.Decompress, false))
            {
                gzipStream.CopyTo(uncompressedStream);
            }

            return(uncompressedStream);
        }
Beispiel #8
0
        /// <summary>
        /// Retrieve a new <c>MemoryStream</c> object with the contents contained zipped data writen from the unzipped
        /// bytes in <c>ReadOnlyMemory&lt;byte&gt;</c>.
        /// </summary>
        /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks>
        /// <param name="data"></param>
        /// <returns></returns>
        public MemoryStream CompressToStream(ReadOnlyMemory <byte> inputData)
        {
            Guard.AgainstEmpty(inputData, nameof(inputData));

            var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider));

            using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true))
            {
                gzipStream.Write(inputData.Span);
            }

            compressedStream.Seek(0, SeekOrigin.Begin);
            return(compressedStream);
        }
Beispiel #9
0
        /// <summary>
        /// Retrieve a new <c>MemoryStream</c> object with the contents contained zipped data writen from the unzipped
        /// bytes in <c>ReadOnlyMemory&lt;byte&gt;</c>.
        /// </summary>
        /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks>
        /// <param name="data"></param>
        /// <returns></returns>
        public async ValueTask <MemoryStream> CompressToStreamAsync(ReadOnlyMemory <byte> inputData)
        {
            Guard.AgainstEmpty(inputData, nameof(inputData));

            var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider));

            using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true))
            {
                await gzipStream
                .WriteAsync(inputData)
                .ConfigureAwait(false);
            }

            compressedStream.Seek(0, SeekOrigin.Begin);
            return(compressedStream);
        }
Beispiel #10
0
        /// <summary>
        /// Returns a new MemoryStream() that has decompressed data inside. Original stream is closed/disposed.
        /// <para>Use <c>RecyclableManager.ReturnStream()</c> to return the <c>MemoryStream</c> when you are ready to dispose of it.</para>
        /// </summary>
        /// <param name="compressedStream"></param>
        /// <param name="leaveStreamOpen"></param>
        /// <returns></returns>
        public MemoryStream Decompress(Stream compressedStream, bool leaveStreamOpen = false)
        {
            Guard.AgainstNullOrEmpty(compressedStream, nameof(compressedStream));

            if (compressedStream.Position == compressedStream.Length)
            {
                compressedStream.Seek(0, SeekOrigin.Begin);
            }

            var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider), CompressionHelpers.GetGzipUncompressedLength(compressedStream));

            using (var gzipStream = new GZipStream(compressedStream, CompressionMode.Decompress, leaveStreamOpen))
            {
                gzipStream.CopyTo(uncompressedStream);
            }

            return(uncompressedStream);
        }
        /// <summary>
        /// Returns a new <c>MemoryStream</c> that has decompressed data inside. The provided stream is optionally closed.
        /// </summary>
        /// <param name="compressedStream"></param>
        /// <param name="leaveStreamOpen"></param>
        /// <returns></returns>
        public async ValueTask <MemoryStream> DecompressAsync(Stream compressedStream, bool leaveStreamOpen = false)
        {
            Guard.AgainstNullOrEmpty(compressedStream, nameof(compressedStream));

            if (compressedStream.Position == compressedStream.Length)
            {
                compressedStream.Seek(0, SeekOrigin.Begin);
            }

            var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableBrotliProvider));

            using (var brotliStream = new BrotliStream(compressedStream, CompressionMode.Decompress, leaveStreamOpen))
            {
                await brotliStream
                .CopyToAsync(uncompressedStream)
                .ConfigureAwait(false);
            }

            return(uncompressedStream);
        }
Beispiel #12
0
        public ArraySegment <byte> Compress(ReadOnlyMemory <byte> inputData)
        {
            Guard.AgainstEmpty(inputData, nameof(inputData));

            var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider));

            using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true))
            {
                gzipStream.Write(inputData.Span);
            }

            if (compressedStream.TryGetBuffer(out var buffer))
            {
                return(buffer);
            }
            else
            {
                using (compressedStream) // dispose stream after allocation.
                {
                    return(compressedStream.ToArray());
                }
            }
        }
        /// <summary>
        /// Retrieve a new <c>MemoryStream</c> object with the contents unzipped and copied from the provided
        /// stream. The provided stream is optionally closed.
        /// </summary>
        /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks>
        /// <param name="data"></param>
        /// <param name="leaveStreamOpen"></param>
        /// <returns></returns>
        public MemoryStream Compress(Stream inputStream, bool leaveStreamOpen = false)
        {
            Guard.AgainstNullOrEmpty(inputStream, nameof(inputStream));

            if (inputStream.Position == inputStream.Length)
            {
                inputStream.Seek(0, SeekOrigin.Begin);
            }

            var compressedStream = RecyclableManager.GetStream(nameof(RecyclableBrotliProvider));

            using (var brotliStream = new BrotliStream(compressedStream, CompressionLevel, true))
            {
                inputStream.CopyTo(brotliStream);
            }
            if (!leaveStreamOpen)
            {
                inputStream.Close();
            }

            compressedStream.Seek(0, SeekOrigin.Begin);
            return(compressedStream);
        }
        public ArraySegment <byte> Decompress(ReadOnlyMemory <byte> compressedData)
        {
            Guard.AgainstEmpty(compressedData, nameof(compressedData));

            var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableBrotliProvider));

            using (var brotliStream = new BrotliStream(compressedData.AsStream(), CompressionMode.Decompress, false))
            {
                brotliStream.CopyTo(uncompressedStream);
            }

            if (uncompressedStream.TryGetBuffer(out var buffer))
            {
                return(buffer);
            }
            else
            {
                // dispose stream after allocation.
                using (uncompressedStream)
                {
                    return(uncompressedStream.ToArray());
                }
            }
        }
Beispiel #15
0
 public void Middleware_Input1 <TIn>(TIn input)
 {
     using var serializedStream = RecyclableManager.GetStream(nameof(RecyclableTransformer));
     _middleware.SerializationProvider.Serialize(serializedStream, input);
 }
Beispiel #16
0
        public MemoryStream DecryptToStream(ReadOnlyMemory <byte> encryptedData)
        {
            Guard.AgainstEmpty(encryptedData, nameof(encryptedData));

            return(RecyclableManager.GetStream(nameof(RecyclableAesGcmEncryptionProvider), Decrypt(encryptedData)));
        }
Beispiel #17
0
        public MemoryStream Decrypt(MemoryStream encryptedStream, bool leaveStreamOpen = false)
        {
            Guard.AgainstNullOrEmpty(encryptedStream, nameof(encryptedStream));

            if (encryptedStream.Position == encryptedStream.Length)
            {
                encryptedStream.Seek(0, SeekOrigin.Begin);
            }

            using var aes = new AesGcm(_key.Span);

            var encryptedByteLength  = (int)encryptedStream.Length - AesGcm.NonceByteSizes.MaxSize - AesGcm.TagByteSizes.MaxSize;
            var encryptedBufferBytes = _pool.Rent(encryptedByteLength);
            var tagBytes             = _pool.Rent(AesGcm.TagByteSizes.MaxSize);
            var nonceBytes           = _pool.Rent(AesGcm.NonceByteSizes.MaxSize);

            var bytesRead = encryptedStream.Read(nonceBytes, 0, AesGcm.NonceByteSizes.MaxSize);

            if (bytesRead == 0)
            {
                throw new InvalidDataException();
            }

            bytesRead = encryptedStream.Read(tagBytes, 0, AesGcm.TagByteSizes.MaxSize);
            if (bytesRead == 0)
            {
                throw new InvalidDataException();
            }

            bytesRead = encryptedStream.Read(encryptedBufferBytes, 0, encryptedByteLength);
            if (bytesRead == 0)
            {
                throw new InvalidDataException();
            }

            // Slicing Version
            var nonce = nonceBytes
                        .AsSpan()
                        .Slice(0, AesGcm.NonceByteSizes.MaxSize);

            var tag = tagBytes
                      .AsSpan()
                      .Slice(0, AesGcm.TagByteSizes.MaxSize);

            var encryptedBytes = encryptedBufferBytes
                                 .AsSpan()
                                 .Slice(0, encryptedByteLength);

            var decryptedBytes = new byte[encryptedByteLength];

            aes.Decrypt(nonce, encryptedBytes, tag, decryptedBytes);

            _pool.Return(encryptedBufferBytes);
            _pool.Return(tagBytes);
            _pool.Return(nonceBytes);

            if (!leaveStreamOpen)
            {
                encryptedStream.Close();
            }

            return(RecyclableManager.GetStream(nameof(RecyclableAesGcmEncryptionProvider), decryptedBytes));
        }