예제 #1
0
        private void AuthenticateHeader(IByteBuffer input)
        {
            input.ReadBytes(_macBytes);
            bool isValidMac = _authenticator.CheckMac(_macBytes, true);

            if (!isValidMac)
            {
                throw new CorruptedFrameException("Sender delivered a frame with an invalid header MAC");
            }
        }
예제 #2
0
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            if (_state == FrameDecoderState.WaitingForHeader)
            {
                if (_logger.IsTraceEnabled)
                {
                    _logger.Trace($"Decoding frame header {input.ReadableBytes}");
                }

                if (input.ReadableBytes == 0)
                {
                    _logger.Warn($"{context.Channel.RemoteAddress} sent an empty frame, disconnecting");
                    context.CloseAsync();
                    return;
                }

                if (input.ReadableBytes >= 32)
                {
                    input.ReadBytes(_headerBuffer);
                    if (_logger.IsTraceEnabled)
                    {
                        _logger.Trace($"Decoding encrypted frame header {new Hex(_headerBuffer)}");
                    }

                    _frameMacProcessor.CheckMac(_headerBuffer, 0, 16, true);
                    _frameCipher.Decrypt(_headerBuffer, 0, 16, _headerBuffer, 0);

                    _totalBodySize = _headerBuffer[0] & 0xFF;
                    _totalBodySize = (_totalBodySize << 8) + (_headerBuffer[1] & 0xFF);
                    _totalBodySize = (_totalBodySize << 8) + (_headerBuffer[2] & 0xFF);
                    _state         = FrameDecoderState.WaitingForPayload;

                    int paddingSize = 16 - _totalBodySize % 16;
                    if (paddingSize == 16)
                    {
                        paddingSize = 0;
                    }

                    if (_logger.IsTraceEnabled)
                    {
                        _logger.Trace($"Expecting a message {_totalBodySize} + {paddingSize} + 16");
                    }
                }
                else
                {
                    if (_logger.IsTraceEnabled)
                    {
                        _logger.Trace("Waiting for full 32 bytes of the header");
                    }

                    return;
                }
            }

            if (_state == FrameDecoderState.WaitingForPayload)
            {
                if (_logger.IsTraceEnabled)
                {
                    _logger.Trace($"Decoding payload {input.ReadableBytes}");
                }

                int paddingSize = 16 - _totalBodySize % 16;
                if (paddingSize == 16)
                {
                    paddingSize = 0;
                }

                int    expectedSize = _totalBodySize + paddingSize + MacSize;
                byte[] buffer;
                if (input.ReadableBytes >= expectedSize)
                {
                    buffer = new byte[expectedSize];
                    input.ReadBytes(buffer);
                }
                else
                {
                    return;
                }

                if (_logger.IsTraceEnabled)
                {
                    _logger.Trace($"Decoding encrypted payload {new Hex(buffer)}");
                }

                int frameSize = buffer.Length - MacSize;
                _frameMacProcessor.CheckMac(buffer, 0, frameSize, false);
                _frameCipher.Decrypt(buffer, 0, frameSize, buffer, 0);

                output.Add(Bytes.Concat(_headerBuffer, buffer));

                if (_logger.IsTraceEnabled)
                {
                    _logger.Trace($"Decrypted message {new Hex((byte[])output.Last())}");
                }

                _state = FrameDecoderState.WaitingForHeader;
            }
        }