예제 #1
0
        bool CompareBuffer(IBufferOffsetSize actual, out string message)
        {
            if (Expected.Size != actual.Size)
            {
                message = string.Format(
                    "Blobs differ in size: expected {0}, got {1}.", Expected.Size, actual.Size);
                return(false);
            }

            for (int i = 0; i < Expected.Size; i++)
            {
                var e = Expected.Buffer [Expected.Offset + i];
                var a = actual.Buffer [actual.Offset + i];
                if (e == a)
                {
                    continue;
                }

                message = string.Format(
                    "Blobs differ at element {0}: expected {1:2x}, got {2:2x}.", i, e, a);
                return(false);
            }

            message = null;
            return(true);
        }
예제 #2
0
		public void Add (HandshakeMessage message, IBufferOffsetSize buffer)
		{
			if (message is TlsHelloRequest)
				throw new InvalidOperationException ();
			for (int i = 0; i < hashes.Length; i++)
				hashes [i].TransformBlock (buffer.Buffer, buffer.Offset, buffer.Size);
		}
예제 #3
0
            public void WriteOutput(string name, IBufferOffsetSize buffer)
            {
                var array = new byte [buffer.Size];

                Buffer.BlockCopy(buffer.Buffer, buffer.Offset, array, 0, buffer.Size);
                WriteOutput(name, array);
            }
예제 #4
0
        internal static int InitializeSecurityContext(SSPIInterface secModule, SafeFreeCredentials credentials, ref SafeDeleteContext safeContext, string targetName, ContextFlags inFlags, Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
        {
            if (endianness != Endianness.Native)
            {
                throw new NotSupportedException();
            }

            SetCredentials(secModule, credentials);

            SecurityBuffer inputBuffer = null;

            if (inputBuffers != null)
            {
                if (inputBuffers.Length != 2 || inputBuffers [1].type != BufferType.Empty)
                {
                    throw new NotSupportedException();
                }
                inputBuffer = inputBuffers [0];
            }

            var incoming = GetInputBuffer(inputBuffer);
            IBufferOffsetSize outgoing = null;

            var retval = (int)safeContext.Context.GenerateNextToken(incoming, out outgoing);

            UpdateOutput(outgoing, outputBuffer);
            return(retval);
        }
예제 #5
0
        protected override int DecryptRecord(DisposeContext d, IBufferOffsetSize input, IBufferOffsetSize output)
        {
            if ((input.Size % BlockSize) != 0)
            {
                return(-1);
            }

            int ivSize;
            ICryptoTransform cipher;

            if (!Cipher.HasFixedIV)
            {
                var IV = new byte [BlockSize];
                Buffer.BlockCopy(input.Buffer, input.Offset, IV, 0, BlockSize);
                ivSize = BlockSize;

                DecryptionAlgorithm.IV = IV;
                cipher = d.Add(DecryptionAlgorithm.CreateDecryptor());
            }
            else
            {
                ivSize = 0;
                cipher = decryptionCipher;
            }

            var ret = cipher.TransformBlock(input.Buffer, input.Offset + ivSize, input.Size - ivSize, output.Buffer, output.Offset);

            if (ret <= 0 || ret != input.Size - ivSize)
            {
                return(-1);
            }

            return(ret);
        }
예제 #6
0
        protected override void EncryptRecord(DisposeContext d, IBufferOffsetSize input)
        {
            ICryptoTransform cipher;

            if (!Cipher.HasFixedIV)
            {
                EncryptionAlgorithm.GenerateIV();
                cipher = d.Add(EncryptionAlgorithm.CreateEncryptor());
            }
            else
            {
                cipher = encryptionCipher;
            }

            if (!Cipher.HasFixedIV)
            {
                Buffer.BlockCopy(EncryptionAlgorithm.IV, 0, input.Buffer, input.Offset, BlockSize);
            }

            var ret = cipher.TransformBlock(input.Buffer, input.Offset + HeaderSize, input.Size - HeaderSize, input.Buffer, input.Offset + HeaderSize);

            if (ret <= 0 || ret != input.Size - HeaderSize)
            {
                throw new InvalidOperationException();
            }

            if (Cipher.HasFixedIV)
            {
                var IV = new byte [BlockSize];
                Buffer.BlockCopy(input.Buffer, input.Offset + input.Size - BlockSize, IV, 0, BlockSize);
                EncryptionAlgorithm.IV = IV;
            }
        }
예제 #7
0
        public IBufferOffsetSize Encrypt(ContentType contentType, IBufferOffsetSize data)
        {
            var output = new BufferOffsetSize(GetEncryptedSize(data.Size));
            var ret    = Encrypt(contentType, data, output);

            output.TruncateTo(ret);
            return(output);
        }
예제 #8
0
        public IBufferOffsetSize Decrypt(ContentType contentType, IBufferOffsetSize input)
        {
            var output = new BufferOffsetSize(input.Size);
            var ret    = Decrypt(contentType, input, output);

            output.TruncateTo(ret);
            return(output);
        }
예제 #9
0
        protected void CheckOutput(TestContext ctx, string name, IBufferOffsetSize buffer)
        {
            var array = new byte [buffer.Size];

            Buffer.BlockCopy(buffer.Buffer, buffer.Offset, array, 0, buffer.Size);
            var data = GetField(name);

            ctx.Assert(array, Is.EqualTo(data), "output");
        }
예제 #10
0
        protected override int Decrypt(DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output)
        {
            var implicitNonce = IsClient ? ServerWriteIV : ClientWriteIV;
            var writeKey      = IsClient ? ServerWriteKey : ClientWriteKey;

                        #if DEBUG_FULL
            if (Cipher.EnableDebugging)
            {
                DebugHelper.WriteLine("FIXED IV", implicitNonce);
                DebugHelper.WriteLine("WRITE KEY", writeKey);
                DebugHelper.WriteLine("SEQUENCE: {0}", ReadSequenceNumber);
            }
                        #endif

            var length = input.Size - ExplicitNonceSize;

            var aad = new TlsBuffer(13);
            aad.Write(ReadSequenceNumber);
            aad.Write((byte)contentType);
            aad.Write((short)Protocol);
            aad.Write((short)(length - MacSize));

                        #if DEBUG_FULL
            if (Cipher.EnableDebugging)
            {
                DebugHelper.WriteFull("TAG", aad);
            }
                        #endif

            var gcm = new GcmBlockCipher(new AesEngine());
            var key = new KeyParameter(writeKey.Buffer);

            var nonce = d.CreateBuffer(ImplicitNonceSize + ExplicitNonceSize);
            Buffer.BlockCopy(implicitNonce.Buffer, 0, nonce.Buffer, 0, ImplicitNonceSize);
            Buffer.BlockCopy(input.Buffer, input.Offset, nonce.Buffer, ImplicitNonceSize, ExplicitNonceSize);

                        #if DEBUG_FULL
            if (Cipher.EnableDebugging)
            {
                DebugHelper.WriteLine("NONCE", nonce);
            }
                        #endif

            var parameters = new AeadParameters(key, 128, nonce.Buffer, aad.Buffer);
            gcm.Init(false, parameters);

            int ret;
            try {
                ret = gcm.ProcessBytes(input.Buffer, input.Offset + ExplicitNonceSize, length, output.Buffer, output.Offset);

                ret += gcm.DoFinal(output.Buffer, output.Offset + ret);
            } catch (CryptoException ex) {
                throw new TlsException(AlertDescription.BadRecordMAC, ex.Message);
            }

            return(ret);
        }
예제 #11
0
        protected void WriteAndCheckOutput(TestContext ctx, string name, IBufferOffsetSize buffer)
        {
            if (generator != null)
            {
                generator.WriteOutput(name, buffer);
                return;
            }

            CheckOutput(ctx, name, buffer);
        }
예제 #12
0
        protected void WriteOutput(string name, IBufferOffsetSize buffer)
        {
            if (generator != null)
            {
                generator.WriteOutput(name, buffer);
                return;
            }

            CheckOutput(name, buffer);
        }
예제 #13
0
파일: TlsBuffer.cs 프로젝트: zixing131/mono
        protected override void Clear()
        {
            var disposable = innerBuffer as IDisposable;

            if (disposable != null)
            {
                disposable.Dispose();
            }
            innerBuffer = null;
            Position    = 0;
        }
예제 #14
0
 protected byte[] ComputeRecordMAC(ContentType contentType, IBufferOffsetSize fragment)
 {
     if (IsServer)
     {
         return(ComputeClientRecordMAC(contentType, fragment));
     }
     else
     {
         return(ComputeServerRecordMAC(contentType, fragment));
     }
 }
예제 #15
0
 public void Add(HandshakeMessage message, IBufferOffsetSize buffer)
 {
     if (message is TlsHelloRequest)
     {
         throw new InvalidOperationException();
     }
     for (int i = 0; i < hashes.Length; i++)
     {
         hashes [i].TransformBlock(buffer.Buffer, buffer.Offset, buffer.Size);
     }
 }
예제 #16
0
        internal byte[] EncodeRecord(ContentType contentType, IBufferOffsetSize buffer)
        {
            int fragmentSize = MAX_FRAGMENT_SIZE;

                        #if INSTRUMENTATION
            if (HasInstrument(HandshakeInstrumentType.FragmentHandshakeMessages))
            {
                fragmentSize = 512;
            }
                        #endif

            return(EncodeRecord_internal(contentType, buffer, fragmentSize));
        }
예제 #17
0
		static byte[] ComputeRecordMAC (TlsProtocolCode protocol, HMac hmac, ulong seqnum, ContentType contentType, IBufferOffsetSize fragment)
		{
			var header = new TlsBuffer (13);
			header.Write (seqnum);
			header.Write ((byte)contentType);
			header.Write ((short)protocol);
			header.Write ((short)fragment.Size);

			hmac.Reset ();
			hmac.TransformBlock (header.Buffer, 0, header.Size);
			hmac.TransformBlock (fragment.Buffer, fragment.Offset, fragment.Size);
			return hmac.TransformFinalBlock ();
		}
예제 #18
0
        internal byte[] EncodeRecord(ContentType contentType, IBufferOffsetSize buffer)
        {
            CheckValid();
            var protocol = HasNegotiatedProtocol ? NegotiatedProtocol : Configuration.RequestedProtocol;

            var output = new TlsStream();

            EncodeRecord(protocol, contentType, Session != null ? Session.Write : null, buffer, output);
            output.Finish();

            var result = new byte [output.Size];

            Buffer.BlockCopy(output.Buffer, output.Offset, result, 0, output.Size);
            return(result);
        }
예제 #19
0
 static void UpdateOutput(IBufferOffsetSize buffer, SecurityBuffer outputBuffer)
 {
     if (buffer != null)
     {
         outputBuffer.token  = buffer.Buffer;
         outputBuffer.offset = buffer.Offset;
         outputBuffer.size   = buffer.Size;
         outputBuffer.type   = BufferType.Token;
     }
     else
     {
         outputBuffer.token = null;
         outputBuffer.size  = outputBuffer.offset = 0;
         outputBuffer.type  = BufferType.Empty;
     }
 }
예제 #20
0
        protected override int Encrypt(DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output)
        {
            // Calculate message MAC
            byte[] mac = null;
            if (IsServer)
            {
                mac = ComputeServerRecordMAC(contentType, input);
            }
            else
            {
                mac = ComputeClientRecordMAC(contentType, input);
            }

                        #if DEBUG_FULL
            if (Cipher.EnableDebugging)
            {
                DebugHelper.WriteLine("RECORD MAC", mac);
            }
                        #endif

            int  plen;
            byte padLen;
            int  totalLength = GetEncryptedSize(input.Size, out plen, out padLen);

            var totalOutput  = new BufferOffsetSize(output.Buffer, output.Offset, totalLength);
            var outputWriter = new TlsBuffer(totalOutput);

            outputWriter.Position += HeaderSize;

            outputWriter.Write(input.Buffer, input.Offset, input.Size);
            outputWriter.Write(mac);

            for (int i = 0; i <= padLen; i++)
            {
                outputWriter.Write(padLen);
            }

            // Encrypt the message
            EncryptRecord(d, totalOutput);
            return(totalLength);
        }
예제 #21
0
        protected override void EncryptRecord(DisposeContext d, IBufferOffsetSize buffer)
        {
            ICryptoTransform cipher;

            if (!Cipher.HasFixedIV)
            {
                EncryptionAlgorithm.GenerateIV();
                cipher = d.Add(EncryptionAlgorithm.CreateEncryptor());
            }
            else
            {
                cipher = encryptionCipher;
            }

            if (!Cipher.HasFixedIV)
            {
                Buffer.BlockCopy(EncryptionAlgorithm.IV, 0, buffer.Buffer, buffer.Offset, BlockSize);
            }

            cipher.TransformBlock(buffer.Buffer, buffer.Offset + HeaderSize, buffer.Size - HeaderSize, buffer.Buffer, buffer.Offset + HeaderSize);
        }
예제 #22
0
파일: TlsBuffer.cs 프로젝트: zixing131/mono
        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);
        }
예제 #23
0
		bool CompareBuffer (IBufferOffsetSize actual, out string message)
		{
			if (Expected.Size != actual.Size) {
				message = string.Format (
					"Blobs differ in size: expected {0}, got {1}.", Expected.Size, actual.Size);
				return false;
			}

			for (int i = 0; i < Expected.Size; i++) {
				var e = Expected.Buffer [Expected.Offset + i];
				var a = actual.Buffer [actual.Offset + i];
				if (e == a)
					continue;

				message = string.Format (
					"Blobs differ at element {0}: expected {1:2x}, got {2:2x}.", i, e, a);
				return false;
			}

			message = null;
			return true;
		}
예제 #24
0
        public int Decrypt(ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output)
        {
            if (output == null || output == input || output.Buffer == input.Buffer)
            {
                throw new TlsException(AlertDescription.InternalError, "In-place decryption is not supported.");
            }
            if (output.Size < input.Size)
            {
                throw new TlsException(AlertDescription.InternalError, "Output buffer overflow.");
            }

            using (var d = new DisposeContext()) {
                var ret = Decrypt(d, contentType, input, output);

                // Update sequence number
                ReadSequenceNumber++;

                if (ret < 0)
                {
                    throw new TlsException(AlertDescription.BadRecordMAC);
                }
                return(ret);
            }
        }
예제 #25
0
		protected override int DecryptRecord (DisposeContext d, IBufferOffsetSize input, IBufferOffsetSize output)
		{
			if ((input.Size % BlockSize) != 0)
				return -1;

			int ivSize;
			ICryptoTransform cipher;
			if (!Cipher.HasFixedIV) {
				var IV = new byte [BlockSize];
				Buffer.BlockCopy (input.Buffer, input.Offset, IV, 0, BlockSize);
				ivSize = BlockSize;

				DecryptionAlgorithm.IV = IV;
				cipher = d.Add (DecryptionAlgorithm.CreateDecryptor ());
			} else {
				ivSize = 0;
				cipher = decryptionCipher;
			}

			var ret = cipher.TransformBlock (input.Buffer, input.Offset + ivSize, input.Size - ivSize, output.Buffer, output.Offset);
			if (ret <= 0 || ret != input.Size - ivSize)
				return -1;

			if (Cipher.HasFixedIV) {
				var IV = new byte [BlockSize];
				Buffer.BlockCopy (input.Buffer, input.Offset + input.Size - BlockSize, IV, 0, BlockSize);
				DecryptionAlgorithm.IV = IV;
			}

			return ret;
		}
예제 #26
0
 public int Decrypt(IBufferOffsetSize input, IBufferOffsetSize output)
 {
     crypto.ReadSequenceNumber = 0;
     return(crypto.Decrypt(ContentType.ApplicationData, input, output));
 }
예제 #27
0
		public IBufferOffsetSize Encrypt (ContentType contentType, IBufferOffsetSize data)
		{
			var output = new BufferOffsetSize (GetEncryptedSize (data.Size));
			var ret = Encrypt (contentType, data, output);
			output.TruncateTo (ret);
			return output;
		}
예제 #28
0
		public static void EncodeRecord (TlsProtocolCode protocol, ContentType contentType, CryptoParameters crypto, IBufferOffsetSize buffer, TlsStream output)
		{
			EncodeRecord_internal (protocol, contentType, crypto, buffer, output);
		}
예제 #29
0
 public void EncryptRecord(ContentType contentType, IBufferOffsetSize input, TlsStream output)
 {
     crypto.WriteSequenceNumber = 0;
     TlsContext.EncodeRecord(Parameters.Protocol, ContentType.ApplicationData, crypto, input, output);
 }
예제 #30
0
 public static void WriteBuffer(string message, IBufferOffsetSize buffer)
 {
     DebugHelper.WriteBuffer(message, buffer.Buffer, buffer.Offset, buffer.Size);
 }
예제 #31
0
		protected override int Decrypt (DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output)
		{
			if ((input.Size % BlockSize) != 0)
				return -1;
			if (input.Size < MinExtraEncryptedBytes)
				return -1;

			var plen = DecryptRecord (d, input, output);
			if (plen <= 0)
				return -1;

			var padlen = output.Buffer [output.Offset + plen - 1];
			#if DEBUG_FULL
			if (Cipher.EnableDebugging) {
				DebugHelper.WriteLine ("DECRYPT: {0} {1} {2}", input.Size, plen, padlen);
				DebugHelper.WriteBuffer ("DECRYPTED", output.Buffer, output.Offset, plen);
			}
			#endif

			/*
			 * VERY IMPORTANT:
			 * 
			 * The Compiler and JIT *** MUST NOT *** optimize the following block of code.
			 * 
			 * It is essential that the dummy checks and dummy calls be kept in place.
			 * Also do not put any debugging code into that region as it would mess up with
			 * the timing.
			 * 
			 */

			#region The following block of code *** MUST NOT *** be optimized in any way

			if (MacSize + padlen + 1 > plen) {
				// Invalid padding: plaintext is not long enough.

				// First run a loop as if there were 256 bytes of padding, with a dummy check.
				int ok = -1;
				for (int i = 0; i < 256; i++) {
					if (output.Buffer [i % output.Size] != padlen)
						ok--;
				}

				// Now assume there's no padding, compute the MAC over the entire buffer.
				var first = new BufferOffsetSize (output.Buffer, output.Offset, plen - MacSize);
				var invalidMac = ComputeRecordMAC (contentType, first);

				// Constant-time compare - this will always fail, TlsBuffer.ConstantTimeCompare() will return a negative value on error.
				ok += TlsBuffer.ConstantTimeCompare (invalidMac, 0, invalidMac.Length, output.Buffer, output.Offset + plen - MacSize, MacSize);
				return ok;
			} else {
				int ok = 0;
				var resultLength = plen - padlen - MacSize - 1;
				for (int i = 0; i < padlen; i++) {
					if (output.Buffer [output.Offset + resultLength + MacSize + i] != padlen)
						ok--;
				}

				var dummyOk = ok;
				var dummyLen = 256 - padlen - 1;
				for (int i = 0; i < dummyLen; i++) {
					if (output.Buffer [i % output.Size] != padlen)
						dummyOk--;
				}

				if (ok < 0) {
					// Now assume there's no padding, compute the MAC over the entire buffer.
					var first = new BufferOffsetSize (output.Buffer, output.Offset, plen - MacSize);
					var invalidMac = ComputeRecordMAC (contentType, first);

					// Constant-time compare - this will always fail, TlsBuffer.ConstantTimeCompare() will return a negative value on error.
					ok += TlsBuffer.ConstantTimeCompare (invalidMac, 0, invalidMac.Length, output.Buffer, output.Offset + plen - MacSize, MacSize);
					return ok;
				} else {
					var first = new BufferOffsetSize (output.Buffer, output.Offset, resultLength);
					var checkMac = ComputeRecordMAC (contentType, first);

					var L1 = 13 + plen - MacSize;
					var L2 = 13 + plen - padlen - 1 - MacSize;

					var additional = ((L1 - 55) / 64) - ((L2 - 55) / 64);
					if (additional > 0) {
						var algorithm = HMac.CreateHash (Cipher.HashAlgorithmType);
						for (int i = 0; i < additional; i++)
							algorithm.TransformBlock (input.Buffer, input.Offset, BlockSize, null, 0);
					}

					ok += TlsBuffer.ConstantTimeCompare (checkMac, 0, checkMac.Length, output.Buffer, output.Offset + resultLength, MacSize);
					if (ok == 0)
						ok = resultLength;
					return ok;
				}
			}

			#endregion
		}
예제 #32
0
        static internal void EncodeRecord(TlsProtocolCode protocol, ContentType contentType, CryptoParameters crypto, IBufferOffsetSize buffer, TlsStream output)
        {
            var maxExtraBytes = crypto != null ? crypto.MaxExtraEncryptedBytes : 0;

            var offset    = buffer.Offset;
            var remaining = buffer.Size;

            do
            {
                BufferOffsetSize fragment;

                var encryptedSize = crypto != null?crypto.GetEncryptedSize(remaining) : remaining;

                if (encryptedSize <= MAX_FRAGMENT_SIZE)
                {
                    fragment = new BufferOffsetSize(buffer.Buffer, offset, remaining);
                }
                else
                {
                    fragment      = new BufferOffsetSize(buffer.Buffer, offset, MAX_FRAGMENT_SIZE - maxExtraBytes);
                    encryptedSize = crypto != null?crypto.GetEncryptedSize(fragment.Size) : fragment.Size;
                }

                // Write tls message
                output.Write((byte)contentType);
                output.Write((short)protocol);
                output.Write((short)encryptedSize);

                if (crypto != null)
                {
                    output.MakeRoom(encryptedSize);
                    var ret = crypto.Encrypt(contentType, fragment, output.GetRemaining());
                    output.Position += ret;
                }
                else
                {
                    output.Write(fragment.Buffer, fragment.Offset, fragment.Size);
                }

                offset    += fragment.Size;
                remaining -= fragment.Size;
            } while (remaining > 0);
        }
예제 #33
0
		byte[] EncodeRecord_internal (ContentType contentType, IBufferOffsetSize buffer, int fragmentSize = MAX_FRAGMENT_SIZE)
		{
			CheckValid ();
			var protocol = HasNegotiatedProtocol ? NegotiatedProtocol : Configuration.RequestedProtocol;

			var output = new TlsStream ();
			EncodeRecord_internal (protocol, contentType, Session != null ? Session.Write : null, buffer, output, fragmentSize);
			output.Finish ();

			var result = new byte [output.Size];
			Buffer.BlockCopy (output.Buffer, output.Offset, result, 0, output.Size);
			return result;
		}
예제 #34
0
 public static BOSWrapper Wrap(IBufferOffsetSize bos)
 {
     return(bos != null ? new BOSWrapper(bos.Buffer, bos.Offset, bos.Size) : null);
 }
예제 #35
0
		protected override void EncryptRecord (DisposeContext d, IBufferOffsetSize input)
		{
			ICryptoTransform cipher;
			if (!Cipher.HasFixedIV) {
				EncryptionAlgorithm.GenerateIV ();
				cipher = d.Add (EncryptionAlgorithm.CreateEncryptor ());
			} else {
				cipher = encryptionCipher;
			}

			if (!Cipher.HasFixedIV)
				Buffer.BlockCopy (EncryptionAlgorithm.IV, 0, input.Buffer, input.Offset, BlockSize);

			var ret = cipher.TransformBlock (input.Buffer, input.Offset + HeaderSize, input.Size - HeaderSize, input.Buffer, input.Offset + HeaderSize);
			if (ret <= 0 || ret != input.Size - HeaderSize)
				throw new InvalidOperationException ();

			if (Cipher.HasFixedIV) {
				var IV = new byte [BlockSize];
				Buffer.BlockCopy (input.Buffer, input.Offset + input.Size - BlockSize, IV, 0, BlockSize);
				EncryptionAlgorithm.IV = IV;
			}
		}
예제 #36
0
		static void UpdateOutput (IBufferOffsetSize buffer, SecurityBuffer outputBuffer)
		{
			if (buffer != null) {
				outputBuffer.token = buffer.Buffer;
				outputBuffer.offset = buffer.Offset;
				outputBuffer.size = buffer.Size;
				outputBuffer.type = BufferType.Token;
			} else {
				outputBuffer.token = null;
				outputBuffer.size = outputBuffer.offset = 0;
				outputBuffer.type = BufferType.Empty;
			}
		}
예제 #37
0
 public static void WriteLine(string message, IBufferOffsetSize buffer)
 {
     Initialize();
     DebugHelper.WriteLine(String.Format("{0} ({1} bytes)", message, buffer.Size));
     DebugHelper.WriteBuffer(buffer);
 }
예제 #38
0
 public static void WriteBuffer(IBufferOffsetSize buffer)
 {
     WriteBuffer(buffer.Buffer, buffer.Offset, buffer.Size);
 }
예제 #39
0
		public static void WriteBuffer (string message, IBufferOffsetSize buffer)
		{
			DebugHelper.WriteBuffer (message, buffer.Buffer, buffer.Offset, buffer.Size);
		}
예제 #40
0
		internal byte[] EncodeRecord (ContentType contentType, IBufferOffsetSize buffer)
		{
			int fragmentSize = MAX_FRAGMENT_SIZE;
			#if INSTRUMENTATION
			if (HasInstrument (HandshakeInstrumentType.FragmentHandshakeMessages))
				fragmentSize = 512;
			#endif

			return EncodeRecord_internal (contentType, buffer, fragmentSize);
		}
예제 #41
0
			public static BOSWrapper Wrap (IBufferOffsetSize bos)
			{
				return bos != null ? new BOSWrapper (bos.Buffer, bos.Offset, bos.Size) : null;
			}
예제 #42
0
		byte[] ComputeClientRecordMAC (ContentType contentType, IBufferOffsetSize fragment)
		{
			var seqnum = IsClient ? WriteSequenceNumber : ReadSequenceNumber;
			return ComputeRecordMAC (Protocol, ClientHMac, seqnum, contentType, fragment);
		}
예제 #43
0
		public IsEqualBlob (IBufferOffsetSize expected)
		{
			Expected = expected;
		}
예제 #44
0
		protected abstract void EncryptRecord (DisposeContext d, IBufferOffsetSize buffer);
예제 #45
0
		internal byte[] EncodeRecord (ContentType contentType, IBufferOffsetSize buffer)
		{
			CheckValid ();
			var protocol = HasNegotiatedProtocol ? NegotiatedProtocol : Configuration.RequestedProtocol;

			int fragmentSize = MAX_FRAGMENT_SIZE;
			#if INSTRUMENTATION
			if (HasInstrument (HandshakeInstrumentType.FragmentHandshakeMessages))
				fragmentSize = 512;
			#endif

			var output = new TlsStream ();
			EncodeRecord_internal (protocol, contentType, Session != null ? Session.Write : null, buffer, output, fragmentSize);
			output.Finish ();

			var result = new byte [output.Size];
			Buffer.BlockCopy (output.Buffer, output.Offset, result, 0, output.Size);
			return result;
		}
예제 #46
0
 protected abstract int Decrypt(DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output);
예제 #47
0
		static void EncodeRecord_internal (TlsProtocolCode protocol, ContentType contentType, CryptoParameters crypto, IBufferOffsetSize buffer, TlsStream output,
			int fragmentSize = MAX_FRAGMENT_SIZE)
		{
			var maxExtraBytes = crypto != null ? crypto.MaxExtraEncryptedBytes : 0;

			var offset = buffer.Offset;
			var remaining = buffer.Size;

			#if !INSTRUMENTATION
			fragmentSize = MAX_FRAGMENT_SIZE;
			#endif

			do {
				BufferOffsetSize fragment;

				var encryptedSize = crypto != null ? crypto.GetEncryptedSize (remaining) : remaining;
				if (encryptedSize <= fragmentSize)
					fragment = new BufferOffsetSize (buffer.Buffer, offset, remaining);
				else {
					fragment = new BufferOffsetSize (buffer.Buffer, offset, fragmentSize - maxExtraBytes);
					encryptedSize = crypto != null ? crypto.GetEncryptedSize (fragment.Size) : fragment.Size;
				}

				// Write tls message
				output.Write ((byte)contentType);
				output.Write ((short)protocol);
				output.Write ((short)encryptedSize);

				if (crypto != null) {
					output.MakeRoom (encryptedSize);
					var ret = crypto.Encrypt (contentType, fragment, output.GetRemaining ());
					output.Position += ret;
				} else {
					output.Write (fragment.Buffer, fragment.Offset, fragment.Size);
				}

				offset += fragment.Size;
				remaining -= fragment.Size;
			} while (remaining > 0);
		}
예제 #48
0
		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;
		}
예제 #49
0
 public IBufferOffsetSize Encrypt(IBufferOffsetSize input)
 {
     crypto.WriteSequenceNumber = 0;
     return(crypto.Encrypt(ContentType.ApplicationData, input));
 }
예제 #50
0
		protected override void Clear ()
		{
			var disposable = innerBuffer as IDisposable;
			if (disposable != null)
				disposable.Dispose ();
			innerBuffer = null;
			Position = 0;
		}
예제 #51
0
		public IBufferOffsetSize Decrypt (ContentType contentType, IBufferOffsetSize input)
		{
			var output = new BufferOffsetSize (input.Size);
			var ret = Decrypt (contentType, input, output);
			output.TruncateTo (ret);
			return output;
		}
예제 #52
0
		protected override int Encrypt (DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output)
		{
			// Calculate message MAC
			byte[] mac = null;
			if (IsServer)
				mac = ComputeServerRecordMAC (contentType, input);
			else
				mac = ComputeClientRecordMAC (contentType, input);

			#if DEBUG_FULL
			if (Cipher.EnableDebugging)
				DebugHelper.WriteLine ("RECORD MAC", mac);
			#endif

			int plen;
			byte padLen;
			int totalLength = GetEncryptedSize (input.Size, out plen, out padLen);

			var totalOutput = new BufferOffsetSize (output.Buffer, output.Offset, totalLength);
			var outputWriter = new TlsBuffer (totalOutput);

			outputWriter.Position += HeaderSize;

			outputWriter.Write (input.Buffer, input.Offset, input.Size);
			outputWriter.Write (mac);

			for (int i = 0; i <= padLen; i++)
				outputWriter.Write (padLen);

			// Encrypt the message
			EncryptRecord (d, totalOutput);
			return totalLength;
		}
예제 #53
0
		protected override int Decrypt (DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output)
		{
			var implicitNonce = IsClient ? ServerWriteIV : ClientWriteIV;
			var writeKey = IsClient ? ServerWriteKey : ClientWriteKey;

			#if DEBUG_FULL
			if (Cipher.EnableDebugging) {
				DebugHelper.WriteLine ("FIXED IV", implicitNonce);
				DebugHelper.WriteLine ("WRITE KEY", writeKey);
				DebugHelper.WriteLine ("SEQUENCE: {0}", ReadSequenceNumber);
			}
			#endif

			var length = input.Size - ExplicitNonceSize;

			var aad = new TlsBuffer (13);
			aad.Write (ReadSequenceNumber);
			aad.Write ((byte)contentType);
			aad.Write ((short)Protocol);
			aad.Write ((short)(length - MacSize));

			#if DEBUG_FULL
			if (Cipher.EnableDebugging)
				DebugHelper.WriteFull ("TAG", aad);
			#endif

			var gcm = new GcmBlockCipher (new AesEngine ());
			var key = new KeyParameter (writeKey.Buffer);

			var nonce = d.CreateBuffer (ImplicitNonceSize + ExplicitNonceSize);
			Buffer.BlockCopy (implicitNonce.Buffer, 0, nonce.Buffer, 0, ImplicitNonceSize);
			Buffer.BlockCopy (input.Buffer, input.Offset, nonce.Buffer, ImplicitNonceSize, ExplicitNonceSize);

			#if DEBUG_FULL
			if (Cipher.EnableDebugging)
				DebugHelper.WriteLine ("NONCE", nonce);
			#endif

			var parameters = new AeadParameters (key, 128, nonce.Buffer, aad.Buffer);
			gcm.Init (false, parameters);

			int ret;
			try {
				ret = gcm.ProcessBytes (input.Buffer, input.Offset + ExplicitNonceSize, length, output.Buffer, output.Offset);

				ret += gcm.DoFinal (output.Buffer, output.Offset + ret);
			} catch (CryptoException ex) {
				throw new TlsException (AlertDescription.BadRecordMAC, ex.Message);
			}

			return ret;
		}
예제 #54
0
		protected byte[] ComputeRecordMAC (ContentType contentType, IBufferOffsetSize fragment)
		{
			if (IsServer)
				return ComputeClientRecordMAC (contentType, fragment);
			else
				return ComputeServerRecordMAC (contentType, fragment);
		}
예제 #55
0
		public void Write (IBufferOffsetSize buffer)
		{
			Write (buffer.Buffer, buffer.Offset, buffer.Size);
		}
예제 #56
0
		protected abstract int Decrypt (DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output);
예제 #57
0
		protected void SetBuffer (byte[] buffer, int offset, int size)
		{
			innerBuffer = new BufferOffsetSize (buffer, offset, size);
		}
예제 #58
0
		public int Decrypt (ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output)
		{
			if (output == null || output == input || output.Buffer == input.Buffer)
				throw new TlsException (AlertDescription.InternalError, "In-place decryption is not supported.");
			if (output.Size < input.Size)
				throw new TlsException (AlertDescription.InternalError, "Output buffer overflow.");

			using (var d = new DisposeContext ()) {
				var ret = Decrypt (d, contentType, input, output);

				// Update sequence number
				ReadSequenceNumber++;

				if (ret < 0)
					throw new TlsException (AlertDescription.BadRecordMAC);
				return ret;
			}
		}
예제 #59
0
		public TlsBuffer (IBufferOffsetSize bos)
		{
			innerBuffer = bos;
			Position = bos.Offset;
		}
예제 #60
0
		protected abstract int DecryptRecord (DisposeContext d, IBufferOffsetSize input, IBufferOffsetSize output);