示例#1
0
        /// <inheritdoc cref="IMessageReader.ReadFrom"/>
        public IMessage ReadFrom(ref SpanBufferReader bufferReader, byte packetProperty)
        {
            if (packetProperty != 0x00)
            {
                var readPacketProperty = bufferReader.ReadUInt8();
                if (readPacketProperty != packetProperty)
                {
                    throw new InvalidDataContractException(
                              "Invalid packet property " +
                              $"(PacketProperty={readPacketProperty}, Expected={packetProperty})."
                              );
                }
            }
            var messageGroup = bufferReader.ReadUInt32();

            if (!_messageRegistries.TryGetValue(messageGroup, out var messageRegistry))
            {
                throw new InvalidDataContractException($"Invalid message group (MessageGroup={messageGroup}).");
            }
            var protocolVersion = bufferReader.ReadVarUInt();

            if (protocolVersion != ProtocolVersion)
            {
                throw new InvalidDataContractException($"Invalid message protocol version (ProtocolVersion={protocolVersion}).");
            }
            var length = bufferReader.ReadVarUInt();

            if (bufferReader.RemainingSize < length)
            {
                throw new InvalidDataContractException($"Message truncated (RemainingSize={bufferReader.RemainingSize}, Expected={length}).");
            }
            var messageId = bufferReader.ReadVarUInt();

            if (!messageRegistry.TryCreateMessage(messageId, out var message))
            {
                throw new InvalidDataContractException($"Invalid message identifier (MessageId={messageId}).");
            }
            if (message is IReliableRequest)
            {
                ((IReliableRequest)message).RequestId = bufferReader.ReadUInt32();
            }
            if (message is IReliableResponse)
            {
                ((IReliableResponse)message).ResponseId = bufferReader.ReadUInt32();
            }
            message.ReadFrom(ref bufferReader);
            return(message);
        }
        /// <inheritdoc cref="IEncryptedMessageReader.ReadFrom"/>
        public IEncryptedMessage ReadFrom(ref SpanBufferReader bufferReader, byte[] key, HMAC hmac, byte?packetProperty)
        {
            var sequenceId      = bufferReader.ReadUInt32();
            var iv              = bufferReader.ReadBytes(16).ToArray();
            var decryptedBuffer = bufferReader.RemainingData.ToArray();

            using (var cryptoTransform = _aesCryptoServiceProvider.CreateDecryptor(key, iv))
            {
                var bytesWritten = 0;
                for (var i = decryptedBuffer.Length; i >= cryptoTransform.InputBlockSize; i -= bytesWritten)
                {
                    var inputCount = cryptoTransform.CanTransformMultipleBlocks
                        ? (i / cryptoTransform.InputBlockSize * cryptoTransform.InputBlockSize)
                        : cryptoTransform.InputBlockSize;
                    bytesWritten = cryptoTransform.TransformBlock(
                        decryptedBuffer, bytesWritten, inputCount,
                        decryptedBuffer, bytesWritten
                        );
                }
            }

            var paddingByteCount    = decryptedBuffer[decryptedBuffer.Length - 1] + 1;
            var hmacStart           = decryptedBuffer.Length - paddingByteCount - 10;
            var decryptedBufferSpan = decryptedBuffer.AsSpan();
            var hash             = decryptedBufferSpan.Slice(hmacStart, 10);
            var hashBufferWriter = new SpanBufferWriter(stackalloc byte[decryptedBuffer.Length + 4]);

            hashBufferWriter.WriteBytes(decryptedBufferSpan.Slice(0, hmacStart));
            hashBufferWriter.WriteUInt32(sequenceId);
            Span <byte> computedHash = stackalloc byte[32];

            if (!hmac.TryComputeHash(hashBufferWriter.Data, computedHash, out _))
            {
                throw new Exception("Failed to compute message hash.");
            }
            if (!hash.SequenceEqual(computedHash.Slice(0, 10)))
            {
                throw new Exception("Message hash does not match the computed hash.");
            }

            bufferReader = new SpanBufferReader(decryptedBuffer);
            if (_messageReader.ReadFrom(ref bufferReader, packetProperty) is not IEncryptedMessage message)
            {
                throw new Exception(
                          "Successfully decrypted message but failed to cast to type " +
                          $"'{nameof(IEncryptedMessage)}'."
                          );
            }

            message.SequenceId = sequenceId;
            return(message);
        }
示例#3
0
 public override void ReadFrom(ref SpanBufferReader bufferReader)
 {
     MultipartMessageId = bufferReader.ReadUInt32();
     Offset             = bufferReader.ReadVarUInt();
     Length             = bufferReader.ReadVarUInt();
     TotalLength        = bufferReader.ReadVarUInt();
     if (Length > _maximumLength)
     {
         throw new InvalidDataContractException($"Length must not surpass {_maximumLength} bytes");
     }
     if (TotalLength > _maximumTotalLength)
     {
         throw new InvalidDataContractException($"Length must not surpass {_maximumTotalLength} bytes");
     }
     Data = bufferReader.ReadBytes((int)Length).ToArray();
 }
示例#4
0
 public void ReadFrom(ref SpanBufferReader bufferReader)
 {
     CertificateResponseId = bufferReader.ReadUInt32();
     Random = bufferReader.ReadBytes(32).ToArray();
     Cookie = bufferReader.ReadBytes(32).ToArray();
 }