]> git.deb.at Git - rhonda/impostor.hazel.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorjs6pak <kubastaron@hotmail.com>
Mon, 5 Jul 2021 00:19:28 +0000 (02:19 +0200)
committerjs6pak <kubastaron@hotmail.com>
Mon, 5 Jul 2021 00:31:51 +0000 (02:31 +0200)
1  2 
Hazel/Crypto/Sha256Stream.cs
Hazel/Dtls/DtlsConnectionListener.cs
Hazel/Dtls/Handshake.cs
Hazel/MessageReader.cs
Hazel/MessageWriter.cs

index 0000000000000000000000000000000000000000,0c23f89f6ff72d000d45acdbb85f5f9b82d20725..df05ca1a7e466f987e2d4efdf4129c07ec051ef9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,79 +1,79 @@@
 -namespace Hazel.Crypto
+ using System;
+ using System.Security.Cryptography;
++namespace Impostor.Hazel.Crypto
+ {
+     /// <summary>
+     /// Streams data into a SHA256 digest
+     /// </summary>
+     public class Sha256Stream : IDisposable
+     {
+         /// <summary>
+         /// Size of the SHA256 digest in bytes
+         /// </summary>
+         public const int DigestSize = 32;
+         private SHA256 hash = SHA256.Create();
+         struct EmptyArray
+         {
+             public static readonly byte[] Value = new byte[0];
+         }
+         /// <summary>
+         /// Create a new instance of a SHA256 stream
+         /// </summary>
+         public Sha256Stream()
+         {
+         }
+         /// <summary>
+         /// Release resources associated with the stream
+         /// </summary>
+         public void Dispose()
+         {
+             this.hash?.Dispose();
+             this.hash = null;
+             GC.SuppressFinalize(this);
+         }
+         /// <summary>
+         /// Reset the stream to its initial state
+         /// </summary>
+         public void Reset()
+         {
+             this.hash?.Dispose();
+             this.hash = SHA256.Create();
+         }
+         /// <summary>
+         /// Add data to the stream
+         /// </summary>
+         public void AddData(ByteSpan data)
+         {
+             while (data.Length > 0)
+             {
+                 int offset = this.hash.TransformBlock(data.GetUnderlyingArray(), data.Offset, data.Length, null, 0);
+                 data = data.Slice(offset);
+             }
+         }
+         /// <summary>
+         /// Calculate the final hash of the stream data
+         /// </summary>
+         /// <param name="output">
+         /// Target span to which the hash will be written
+         /// </param>
+         public void CalculateHash(ByteSpan output)
+         {
+             if (output.Length != DigestSize)
+             {
+                 throw new ArgumentException($"Expected a span of {DigestSize} bytes. Got a span of {output.Length} bytes", nameof(output));
+             }
+             this.hash.TransformFinalBlock(EmptyArray.Value, 0, 0);
+             new ByteSpan(this.hash.Hash).CopyTo(output);
+         }
+     }
+ }
index c3b6cceb7acf68a469bf2076b20d38e32f397e55,c6bf31dedaa34e53a8f3872bc43e19e36b113122..5242758fc98649b50636dfcbfb3c84b3ff0179d7
@@@ -2,9 -2,7 +2,8 @@@ using System
  using System.Collections.Concurrent;
  using System.Collections.Generic;
  using System.Diagnostics;
- using System.IO;
  using System.Net;
 +using System.Net.Sockets;
  using System.Security.Cryptography;
  using System.Security.Cryptography.X509Certificates;
  using System.Threading;
Simple merge
index 6e2a555c06b7ec9363aa665e0fb9552caff08174,4e0cd2a6c654530d7f92a1baa28e1b8a99aa0b50..03b0a994f8d679086073d98d39fb3e8264cf1544
  using System;
 -using System.IO;
 -using System.Linq;
 +using System.Buffers.Binary;
 +using System.Numerics;
  using System.Runtime.CompilerServices;
  using System.Text;
 -
 -namespace Hazel
 +using Impostor.Api;
 +using Impostor.Api.Games;
 +using Impostor.Api.Net.Inner;
 +using Impostor.Api.Net.Messages;
 +using Impostor.Api.Unity;
 +using Microsoft.Extensions.ObjectPool;
 +
 +namespace Impostor.Hazel
  {
 -    public class MessageReader : IRecyclable
 +    public class MessageReader : IMessageReader
      {
 -        public static readonly ObjectPool<MessageReader> ReaderPool = new ObjectPool<MessageReader>(() => new MessageReader());
 -
 -        public byte[] Buffer;
 -        public byte Tag;
 +        private readonly ObjectPool<MessageReader> _pool;
 +        private bool _inUse;
  
 -        public int Length;
 -        public int Offset;
 -
 -        public int BytesRemaining => this.Length - this.Position;
 -
 -        private MessageReader Parent;
 -
 -        public int Position
 +        internal MessageReader(ObjectPool<MessageReader> pool)
          {
 -            get { return this._position; }
 -            set
 -            {
 -                this._position = value;
 -                this.readHead = value + Offset;
 -            }
 +            _pool = pool;
          }
  
 -        private int _position;
 -        private int readHead;
 +        public byte[] Buffer { get; private set; }
  
 -        public static MessageReader GetSized(int minSize)
 -        {
 -            var output = ReaderPool.GetObject();
 +        public int Offset { get; internal set; }
  
 -            if (output.Buffer == null || output.Buffer.Length < minSize)
 -            {
 -                output.Buffer = new byte[minSize];
 -            }
 -            else
 -            {
 -                Array.Clear(output.Buffer, 0, output.Buffer.Length);
 -            }
 +        public int Position { get; internal set; }
  
 -            output.Offset = 0;
 -            output.Position = 0;
 -            output.Tag = byte.MaxValue;
 -            return output;
 -        }
 -
 -        public static MessageReader Get(byte[] buffer)
 -        {
 -            var output = ReaderPool.GetObject();
 -
 -            output.Buffer = buffer;
 -            output.Offset = 0;
 -            output.Position = 0;
 -            output.Length = buffer.Length;
 -            output.Tag = byte.MaxValue;
 -
 -            return output;
 -        }
 -
 -        public static MessageReader CopyMessageIntoParent(MessageReader source)
 -        {
 -            var output = MessageReader.GetSized(source.Length + 3);
 -            System.Buffer.BlockCopy(source.Buffer, source.Offset - 3, output.Buffer, 0, source.Length + 3);
 +        public int Length { get; internal set; }
 +        
 +        public int BytesRemaining => this.Length - this.Position;
  
 -            output.Offset = 0;
 -            output.Position = 0;
 -            output.Length = source.Length + 3;
 +        public byte Tag { get; private set; }
  
 -            return output;
 -        }
 +        public MessageReader Parent { get; private set; }
  
 -        public static MessageReader Get(MessageReader source)
 +        private int ReadPosition => Offset + Position;
 +        public void Update(byte[] buffer, int offset = 0, int position = 0, int? length = null, byte tag = byte.MaxValue, MessageReader parent = null)
          {
 -            var output = MessageReader.GetSized(source.Buffer.Length);
 -            System.Buffer.BlockCopy(source.Buffer, 0, output.Buffer, 0, source.Buffer.Length);
 -
 -            output.Offset = source.Offset;
 -
 -            output._position = source._position;
 -            output.readHead = source.readHead;
 -
 -            output.Length = source.Length;
 -            output.Tag = source.Tag;
 -
 -            return output;
 +            _inUse = true;
 +
 +            Buffer = buffer;
 +            Offset = offset;
 +            Position = position;
 +            Length = length ?? buffer.Length;
 +            Tag = tag;
 +            Parent = parent;
          }
  
 -        public static MessageReader Get(byte[] buffer, int offset)
 +        internal void Reset()
          {
 -            // Ensure there is at least a header
 -            if (offset + 3 > buffer.Length) return null;
 -
 -            var output = ReaderPool.GetObject();
 -
 -            output.Buffer = buffer;
 -            output.Offset = offset;
 -            output.Position = 0;
 -
 -            output.Length = output.ReadUInt16();
 -            output.Tag = output.ReadByte();
 -
 -            output.Offset += 3;
 -            output.Position = 0;
 -
 -            return output;
 +            _inUse = false;
 +
 +            Tag = byte.MaxValue;
 +            Buffer = null;
 +            Offset = 0;
 +            Position = 0;
 +            Length = 0;
 +            Parent = null;
          }
  
 -        /// <summary>
 -        /// Produces a MessageReader using the parent's buffer. This MessageReader should **NOT** be recycled.
 -        /// </summary>
 -        public MessageReader ReadMessage()
 +        public IMessageReader ReadMessage()
          {
 -            // Ensure there is at least a header
 -            if (this.BytesRemaining < 3) throw new InvalidDataException($"ReadMessage header is longer than message length: 3 of {this.BytesRemaining}");
 -
 -            var output = new MessageReader();
 -
 -            output.Parent = this;
 -            output.Buffer = this.Buffer;
 -            output.Offset = this.readHead;
 -            output.Position = 0;
 -
 -            output.Length = output.ReadUInt16();
 -            output.Tag = output.ReadByte();
 -
 -            output.Offset += 3;
 -            output.Position = 0;
 +            var length = ReadUInt16();
 +            var tag = FastByte();
 +            var pos = ReadPosition;
  
 -            if (this.BytesRemaining < output.Length + 3) throw new InvalidDataException($"Message Length at Position {this.readHead} is longer than message length: {output.Length + 3} of {this.BytesRemaining}");
 +            Position += length;
  
 -            this.Position += output.Length + 3;
 -            return output;
 +            var reader = _pool.Get();
 +            reader.Update(Buffer, pos, 0, length, tag, this);
 +            return reader;
          }
  
 -        /// <summary>
 -        /// Produces a MessageReader with a new buffer. This MessageReader should be recycled.
 -        /// </summary>
 -        public MessageReader ReadMessageAsNewBuffer()
 +        public void RemoveMessage(IMessageReader message)
          {
 -            if (this.BytesRemaining < 3) throw new InvalidDataException($"ReadMessage header is longer than message length: 3 of {this.BytesRemaining}");
 -
 -            var len = this.ReadUInt16();
 -            var tag = this.ReadByte();
 +            if (message.Buffer != Buffer)
 +            {
 +                throw new ImpostorProtocolException("Tried to remove message from a message that does not have the same buffer.");
 +            }
  
 -            if (this.BytesRemaining < len) throw new InvalidDataException($"Message Length at Position {this.readHead} is longer than message length: {len} of {this.BytesRemaining}");
 +            // Offset of where to start removing.
 +            var offsetStart = message.Offset - 3;
  
 -            var output = MessageReader.GetSized(len);
 +            // Offset of where to end removing.
 +            var offsetEnd = message.Offset + message.Length;
  
 -            output.Parent = this;
 -            Array.Copy(this.Buffer, this.readHead, output.Buffer, 0, len);
 +            // The amount of bytes to copy over ourselves.
 +            var lengthToCopy = message.Buffer.Length - offsetEnd;
  
 -            output.Length = len;
 -            output.Tag = tag;
 +            System.Buffer.BlockCopy(Buffer, offsetEnd, Buffer, offsetStart, lengthToCopy);
  
 -            this.Position += output.Length;
 -            return output;
 +            ((MessageReader) message).Parent.AdjustLength(message.Offset, message.Length + 3);
          }
  
 -        public MessageWriter StartWriter()
++        public void InsertMessage(IMessageReader reader, IMessageWriter writer)
+         {
 -            var output = new MessageWriter(this.Buffer);
 -            output.Position = this.readHead;
 -            return output;
 -        }
 -
 -        public void RemoveMessage(MessageReader reader)
 -        {
 -            var temp = MessageReader.GetSized(reader.Buffer.Length);
 -            try
 -            {
 -                var headerOffset = reader.Offset - 3;
 -                var endOfMessage = reader.Offset + reader.Length;
 -                var len = reader.Buffer.Length - endOfMessage;
 -
 -                Array.Copy(reader.Buffer, endOfMessage, temp.Buffer, 0, len);
 -                Array.Copy(temp.Buffer, 0, this.Buffer, headerOffset, len);
 -
 -                this.AdjustLength(reader.Offset, reader.Length + 3);
 -            }
 -            finally
 -            {
 -                temp.Recycle();
 -            }
 -        }
 -
 -        public void InsertMessage(MessageReader reader, MessageWriter writer)
 -        {
 -            var temp = MessageReader.GetSized(reader.Buffer.Length);
 -            try 
 -            {
 -                var headerOffset = reader.Offset - 3;
 -                var startOfMessage = reader.Offset;
 -                var len = reader.Buffer.Length - startOfMessage;
 -                int writerOffset = 3;
 -                switch (writer.SendOption)
 -                {
 -                    case SendOption.Reliable:
 -                        writerOffset = 3;
 -                        break;
 -                    case SendOption.None:
 -                        writerOffset = 1;
 -                        break;
 -                }
 -                
 -                //store the original buffer in temp
 -                Array.Copy(reader.Buffer, headerOffset, temp.Buffer, 0, len);
 -
 -                //put the contents of writer in at headerOffset
 -                Array.Copy(writer.Buffer, writerOffset, this.Buffer, headerOffset, writer.Length-writerOffset);
 -
 -                //put the original buffer in after that
 -                Array.Copy(temp.Buffer, 0, this.Buffer, headerOffset + (writer.Length-writerOffset), len - writer.Length);
 -
 -                this.AdjustLength(-1 * reader.Offset , -1 * (writer.Length - writerOffset));
 -            }
 -            finally
 -            {
 -                temp.Recycle();
 -            }
++            throw new NotImplementedException();
+         }
          private void AdjustLength(int offset, int amount)
          {
 -            if (this.readHead > offset)
 +            this.Length -= amount;
 +
 +            if (this.ReadPosition > offset)
              {
                  this.Position -= amount;
              }
              return output;
          }
  
 -            ulong output = (ulong)this.FastByte()
 -                | (ulong)this.FastByte() << 8
 -                | (ulong)this.FastByte() << 16
 -                | (ulong)this.FastByte() << 24
 -                | (ulong)this.FastByte() << 32
 -                | (ulong)this.FastByte() << 40
 -                | (ulong)this.FastByte() << 48
 -                | (ulong)this.FastByte() << 56;
 -
+         public ulong ReadUInt64()
+         {
 -            long output = (long)this.FastByte()
 -                | (long)this.FastByte() << 8
 -                | (long)this.FastByte() << 16
 -                | (long)this.FastByte() << 24
 -                | (long)this.FastByte() << 32
 -                | (long)this.FastByte() << 40
 -                | (long)this.FastByte() << 48
 -                | (long)this.FastByte() << 56;
 -
++            var output = BinaryPrimitives.ReadUInt64LittleEndian(Buffer.AsSpan(ReadPosition));
++            Position += sizeof(ulong);
+             return output;
+         }
+         public long ReadInt64()
+         {
++            var output = BinaryPrimitives.ReadInt64LittleEndian(Buffer.AsSpan(ReadPosition));
++            Position += sizeof(long);
+             return output;
+         }
          public unsafe float ReadSingle()
          {
 -            float output = 0;
 -            fixed (byte* bufPtr = &this.Buffer[this.readHead])
 -            {
 -                byte* outPtr = (byte*)&output;
 -
 -                *outPtr = *bufPtr;
 -                *(outPtr + 1) = *(bufPtr + 1);
 -                *(outPtr + 2) = *(bufPtr + 2);
 -                *(outPtr + 3) = *(bufPtr + 3);
 -            }
 -
 -            this.Position += 4;
 +            var output = BinaryPrimitives.ReadSingleLittleEndian(Buffer.AsSpan(ReadPosition));
 +            Position += sizeof(float);
              return output;
          }
  
Simple merge