Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mcs/class/Mono.Security/Mono.Security.Interface/TlsBuffer.cs')
-rw-r--r--mcs/class/Mono.Security/Mono.Security.Interface/TlsBuffer.cs334
1 files changed, 334 insertions, 0 deletions
diff --git a/mcs/class/Mono.Security/Mono.Security.Interface/TlsBuffer.cs b/mcs/class/Mono.Security/Mono.Security.Interface/TlsBuffer.cs
new file mode 100644
index 00000000000..be3c007b5b5
--- /dev/null
+++ b/mcs/class/Mono.Security/Mono.Security.Interface/TlsBuffer.cs
@@ -0,0 +1,334 @@
+//
+// TlsBuffer.cs
+//
+// Author:
+// Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2014-2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+
+namespace Mono.Security.Interface
+{
+ public class TlsBuffer : SecretParameters
+ {
+ public int Position {
+ get; set;
+ }
+
+ public int Remaining {
+ get { return Size - (Position - Offset); }
+ }
+
+ public byte[] Buffer {
+ get { return innerBuffer.Buffer; }
+ }
+
+ public int Offset {
+ get { return innerBuffer.Offset; }
+ }
+
+ public int Size {
+ get { return innerBuffer.Size; }
+ }
+
+ public int EndOffset {
+ get { return Offset + Size; }
+ }
+
+ IBufferOffsetSize innerBuffer;
+
+ protected TlsBuffer ()
+ : this (null, 0, 0)
+ {
+ }
+
+ public TlsBuffer (IBufferOffsetSize bos)
+ {
+ innerBuffer = bos;
+ Position = bos.Offset;
+ }
+
+ public TlsBuffer (byte[] buffer, int offset, int size)
+ : this (new BufferOffsetSize (buffer, offset, size))
+ {
+ }
+
+ public TlsBuffer (byte[] buffer)
+ : this (buffer, 0, buffer.Length)
+ {
+ }
+
+ public TlsBuffer (int size)
+ : this (new byte [size], 0, size)
+ {
+ }
+
+ public byte ReadByte ()
+ {
+ if (Position >= EndOffset)
+ throw new TlsException (AlertDescription.DecodeError, "Buffer overflow");
+ return Buffer [Position++];
+ }
+
+ public short ReadInt16 ()
+ {
+ if (Position + 1 >= EndOffset)
+ throw new TlsException (AlertDescription.DecodeError, "Buffer overflow");
+ var retval = (short)(Buffer [Position] << 8 | Buffer [Position + 1]);
+ Position += 2;
+ return retval;
+ }
+
+ public int ReadInt24 ()
+ {
+ if (Position + 2 >= EndOffset)
+ throw new TlsException (AlertDescription.DecodeError, "Buffer overflow");
+ var retval = ((Buffer [Position] << 16) | (Buffer [Position+1] << 8) | Buffer [Position+2]);
+ Position += 3;
+ return retval;
+ }
+
+ public int ReadInt32 ()
+ {
+ if (Position + 3 >= EndOffset)
+ throw new TlsException (AlertDescription.DecodeError, "Buffer overflow");
+ var retval = ((Buffer [Position] << 24) | (Buffer [Position+1] << 16) | (Buffer [Position+2] << 8) | Buffer [Position+3]);
+ Position += 4;
+ return retval;
+ }
+
+ public TlsBuffer ReadBuffer (int length)
+ {
+ if (Position + length > EndOffset)
+ throw new TlsException (AlertDescription.DecodeError, "Buffer overflow");
+ var retval = new TlsBuffer (Buffer, Position, length);
+ Position += length;
+ return retval;
+ }
+
+ public IBufferOffsetSize GetRemaining ()
+ {
+ return new BufferOffsetSize (Buffer, Position, Remaining);
+ }
+
+ protected virtual void MakeRoomInternal (int size)
+ {
+ if (Position + size > EndOffset)
+ throw new TlsException (AlertDescription.DecodeError, "Buffer overflow");
+ }
+
+ public void Write (byte value)
+ {
+ MakeRoomInternal (1);
+ Buffer [Position++] = value;
+ }
+
+ public void Write (short value)
+ {
+ MakeRoomInternal (2);
+ WriteInt16 (Buffer, Position, value);
+ Position += 2;
+ }
+
+ public static void WriteInt16 (byte[] buffer, int offset, short value)
+ {
+ buffer[offset] = ((byte)(value >> 8));
+ buffer[offset+1] = ((byte)value);
+ }
+
+ public void Write (int value)
+ {
+ MakeRoomInternal (4);
+ WriteInt32 (Buffer, Position, value);
+ Position += 4;
+ }
+
+ public void WriteInt24 (int value)
+ {
+ MakeRoomInternal (3);
+ WriteInt24 (Buffer, Position, value);
+ Position += 3;
+ }
+
+ #pragma warning disable 3001
+ public void Write (ulong value)
+ #pragma warning restore 3001
+ {
+ MakeRoomInternal (8);
+ WriteInt64 (Buffer, Position, value);
+ Position += 8;
+ }
+
+ public static void WriteInt24 (byte[] buffer, int offset, int value)
+ {
+ buffer[offset] = ((byte)(value >> 16));
+ buffer[offset+1] = ((byte)(value >> 8));
+ buffer[offset+2] = ((byte)value);
+ }
+
+ public static void WriteInt32 (byte[] buffer, int offset, int value)
+ {
+ buffer[offset] = ((byte)(value >> 24));
+ buffer[offset+1] = ((byte)(value >> 16));
+ buffer[offset+2] = ((byte)(value >> 8));
+ buffer[offset+3] = ((byte)value);
+ }
+
+ #pragma warning disable 3001
+ public static void WriteInt64 (byte[] buffer, int offset, ulong value)
+ #pragma warning restore 3001
+ {
+ buffer[offset] = (byte) (value >> 56);
+ buffer[offset+1] = (byte) (value >> 48);
+ buffer[offset+2] = (byte) (value >> 40);
+ buffer[offset+3] = (byte) (value >> 32);
+ buffer[offset+4] = (byte) (value >> 24);
+ buffer[offset+5] = (byte) (value >> 16);
+ buffer[offset+6] = (byte) (value >> 8);
+ buffer[offset+7] = (byte) value;
+ }
+
+ public void Write (byte[] buffer)
+ {
+ Write (buffer, 0, buffer.Length);
+ }
+
+ public void Write (byte[] buffer, int offset, int size)
+ {
+ MakeRoomInternal (size);
+ Array.Copy (buffer, offset, Buffer, Position, size);
+ Position += size;
+ }
+
+ public void Write (IBufferOffsetSize buffer)
+ {
+ Write (buffer.Buffer, buffer.Offset, buffer.Size);
+ }
+
+ public SecureBuffer ReadSecureBuffer (int count)
+ {
+ return new SecureBuffer (ReadBytes (count));
+ }
+
+ public byte[] ReadBytes (int count)
+ {
+ if (Position + count > EndOffset)
+ throw new TlsException (AlertDescription.DecodeError, "Buffer overflow");
+ var retval = new byte [count];
+ Array.Copy (Buffer, Position, retval, 0, count);
+ Position += count;
+ return retval;
+ }
+
+ internal static bool Compare (SecureBuffer buffer1, SecureBuffer buffer2)
+ {
+ if (buffer1 == null || buffer2 == null)
+ return false;
+
+ if (buffer1.Size != buffer2.Size)
+ return false;
+
+ for (int i = 0; i < buffer1.Size; i++) {
+ if (buffer1.Buffer [i] != buffer2.Buffer [i])
+ return false;
+ }
+ return true;
+ }
+
+ public static bool Compare (IBufferOffsetSize buffer1, IBufferOffsetSize buffer2)
+ {
+ if (buffer1 == null || buffer2 == null)
+ return false;
+
+ if (buffer1.Size != buffer2.Size)
+ return false;
+
+ for (int i = 0; i < buffer1.Size; i++) {
+ if (buffer1.Buffer [buffer1.Offset + i] != buffer2.Buffer [buffer2.Offset + i])
+ return false;
+ }
+ return true;
+ }
+
+ public static bool Compare (byte[] buffer1, byte[] buffer2)
+ {
+ if (buffer1 == null || buffer2 == null)
+ return false;
+
+ return Compare (buffer1, 0, buffer1.Length, buffer2, 0, buffer2.Length);
+ }
+
+ public static bool Compare (byte[] buffer1, int offset1, int size1, byte[] buffer2, int offset2, int size2)
+ {
+ if (buffer1 == null || buffer2 == null)
+ return false;
+
+ if (size1 != size2)
+ return false;
+
+ for (int i = 0; i < size1; i++) {
+ if (buffer1 [offset1 + i] != buffer2 [offset2 + i])
+ return false;
+ }
+ return true;
+
+ }
+
+ public static int ConstantTimeCompare (byte[] buffer1, int offset1, int size1, byte[] buffer2, int offset2, int size2)
+ {
+ int status = 0;
+ int effectiveSize;
+ if (size1 < size2) {
+ status--;
+ effectiveSize = size1;
+ } else if (size2 < size1) {
+ status--;
+ effectiveSize = size2;
+ } else {
+ effectiveSize = size1;
+ }
+
+ for (int i = 0; i < effectiveSize; i++) {
+ if (buffer1 [offset1 + i] != buffer2 [offset2 + i])
+ status--;
+ }
+
+ return status;
+ }
+
+ protected void SetBuffer (byte[] buffer, int offset, int size)
+ {
+ innerBuffer = new BufferOffsetSize (buffer, offset, size);
+ }
+
+ protected override void Clear ()
+ {
+ var disposable = innerBuffer as IDisposable;
+ if (disposable != null)
+ disposable.Dispose ();
+ innerBuffer = null;
+ Position = 0;
+ }
+
+ public static readonly byte[] EmptyArray = new byte [0];
+ }
+}
+