Library.Net.Connections.SecureConnection.Receive C# (CSharp) Method

Receive() public method

public Receive ( System.TimeSpan timeout, Information options ) : Stream
timeout System.TimeSpan
options Information
return Stream
        public override Stream Receive(TimeSpan timeout, Information options)
        {
            if (_disposed) throw new ObjectDisposedException(this.GetType().FullName);
            if (!_connect) throw new ConnectionException();

            lock (_receiveLock)
            {
                try
                {
                    if (_version.HasFlag(SecureConnectionVersion.Version3))
                    {
                        using (Stream stream = _connection.Receive(timeout, options))
                        {
                            byte[] totalReceiveSizeBuff = new byte[8];
                            if (stream.Read(totalReceiveSizeBuff, 0, totalReceiveSizeBuff.Length) != totalReceiveSizeBuff.Length) throw new ConnectionException();
                            long totalReceiveSize = NetworkConverter.ToInt64(totalReceiveSizeBuff);

                            if (_informationVersion3.HashAlgorithm.HasFlag(SecureVersion3.HashAlgorithm.Sha256))
                            {
                                const int hashLength = 32;

                                _totalReceiveSize += (stream.Length - (8 + hashLength));

                                if (totalReceiveSize != _totalReceiveSize) throw new ConnectionException();

                                byte[] otherHmacBuff = new byte[hashLength];
                                stream.Seek(-hashLength, SeekOrigin.End);
                                if (stream.Read(otherHmacBuff, 0, otherHmacBuff.Length) != otherHmacBuff.Length) throw new ConnectionException();
                                stream.SetLength(stream.Length - hashLength);
                                stream.Seek(0, SeekOrigin.Begin);

                                byte[] myHmacBuff = HmacSha256.ComputeHash(stream, _informationVersion3.OtherHmacKey);

                                if (!Unsafe.Equals(otherHmacBuff, myHmacBuff)) throw new ConnectionException();

                                stream.Seek(8, SeekOrigin.Begin);
                            }
                            else
                            {
                                throw new ConnectionException();
                            }

                            var bufferStream = new BufferStream(_bufferManager);

                            if (_informationVersion3.CryptoAlgorithm.HasFlag(SecureVersion3.CryptoAlgorithm.Aes256))
                            {
                                byte[] iv = new byte[16];
                                stream.Read(iv, 0, iv.Length);

                                using (var aes = Aes.Create())
                                {
                                    aes.KeySize = 256;
                                    aes.Mode = CipherMode.CBC;
                                    aes.Padding = PaddingMode.PKCS7;

                                    using (CryptoStream cs = new CryptoStream(new WrapperStream(bufferStream, true), aes.CreateDecryptor(_informationVersion3.OtherCryptoKey, iv), CryptoStreamMode.Write))
                                    using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
                                    {
                                        int length;

                                        while ((length = stream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0)
                                        {
                                            cs.Write(safeBuffer.Value, 0, length);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                throw new ConnectionException();
                            }

                            bufferStream.Seek(0, SeekOrigin.Begin);
                            return bufferStream;
                        }
                    }
                    else
                    {
                        throw new ConnectionException();
                    }
                }
                catch (ConnectionException e)
                {
                    throw e;
                }
                catch (Exception e)
                {
                    throw new ConnectionException(e.Message, e);
                }
            }
        }