Пример #1
0
        public byte[] Expand(string hashName, byte[] secret, byte[] seed, int length)
        {
            int num1 = !(hashName == "MD5") ? 20 : 16;
            int num2 = length / num1;

            if (length % num1 > 0)
            {
                ++num2;
            }
            Mono.Security.Cryptography.HMAC hmac = new Mono.Security.Cryptography.HMAC(hashName, secret);
            TlsStream tlsStream1 = new TlsStream();

            byte[][] numArray1 = new byte[num2 + 1][];
            numArray1[0] = seed;
            for (int index = 1; index <= num2; ++index)
            {
                TlsStream tlsStream2 = new TlsStream();
                hmac.TransformFinalBlock(numArray1[index - 1], 0, numArray1[index - 1].Length);
                numArray1[index] = hmac.Hash;
                tlsStream2.Write(numArray1[index]);
                tlsStream2.Write(seed);
                hmac.TransformFinalBlock(tlsStream2.ToArray(), 0, (int)tlsStream2.Length);
                tlsStream1.Write(hmac.Hash);
                tlsStream2.Reset();
            }
            byte[] numArray2 = new byte[length];
            Buffer.BlockCopy((Array)tlsStream1.ToArray(), 0, (Array)numArray2, 0, numArray2.Length);
            tlsStream1.Reset();
            return(numArray2);
        }
Пример #2
0
        public byte[] PRF(byte[] secret, string label, byte[] data, int length)
        {
            int num = secret.Length >> 1;

            if ((secret.Length & 1) == 1)
            {
                num++;
            }
            TlsStream tlsStream = new TlsStream();

            tlsStream.Write(Encoding.ASCII.GetBytes(label));
            tlsStream.Write(data);
            byte[] seed = tlsStream.ToArray();
            tlsStream.Reset();
            byte[] array = new byte[num];
            Buffer.BlockCopy(secret, 0, array, 0, num);
            byte[] array2 = new byte[num];
            Buffer.BlockCopy(secret, secret.Length - num, array2, 0, num);
            byte[] array3 = Expand("MD5", array, seed, length);
            byte[] array4 = Expand("SHA1", array2, seed, length);
            byte[] array5 = new byte[length];
            for (int i = 0; i < array5.Length; i++)
            {
                array5[i] = (byte)(array3[i] ^ array4[i]);
            }
            return(array5);
        }
		protected override void ProcessHandshakeMessage(TlsStream handMsg)
		{
			HandshakeType		handshakeType	= (HandshakeType)handMsg.ReadByte();
			HandshakeMessage	message			= null;

			DebugHelper.WriteLine(">>>> Processing Handshake record ({0})", handshakeType);

			// Read message length
			int length = handMsg.ReadInt24();

			// Read message data
			byte[] data = new byte[length];
			handMsg.Read(data, 0, length);

			// Create and process the server message
			message = this.createServerHandshakeMessage(handshakeType, data);
			message.Process();

			// Update the last handshake message
			this.Context.LastHandshakeMsg = handshakeType;

			// Update session
			if (message != null)
			{
				message.Update();
			}
		}
Пример #4
0
        public byte[] PRF(byte[] secret, string label, byte[] data, int length)
        {
            int count = secret.Length >> 1;

            if ((secret.Length & 1) == 1)
            {
                ++count;
            }
            TlsStream tlsStream = new TlsStream();

            tlsStream.Write(Encoding.ASCII.GetBytes(label));
            tlsStream.Write(data);
            byte[] array = tlsStream.ToArray();
            tlsStream.Reset();
            byte[] secret1 = new byte[count];
            Buffer.BlockCopy((Array)secret, 0, (Array)secret1, 0, count);
            byte[] secret2 = new byte[count];
            Buffer.BlockCopy((Array)secret, secret.Length - count, (Array)secret2, 0, count);
            byte[] numArray1 = this.Expand("MD5", secret1, array, length);
            byte[] numArray2 = this.Expand("SHA1", secret2, array, length);
            byte[] numArray3 = new byte[length];
            for (int index = 0; index < numArray3.Length; ++index)
            {
                numArray3[index] = (byte)((uint)numArray1[index] ^ (uint)numArray2[index]);
            }
            return(numArray3);
        }
Пример #5
0
        public byte[] EncodeRecord(ContentType contentType, byte[] recordData, int offset, int count)
        {
            if (this.context.SentConnectionEnd)
            {
                throw new TlsException(AlertDescription.InternalError, "The session is finished and it's no longer valid.");
            }
            TlsStream tlsStream = new TlsStream();
            short     num;

            for (int srcOffset = offset; srcOffset < offset + count; srcOffset += (int)num)
            {
                num = count + offset - srcOffset <= 16384 ? (short)(count + offset - srcOffset) : (short)16384;
                byte[] numArray = new byte[(int)num];
                Buffer.BlockCopy((Array)recordData, srcOffset, (Array)numArray, 0, (int)num);
                if (this.Context.Write != null && this.Context.Write.Cipher != null)
                {
                    numArray = this.encryptRecordFragment(contentType, numArray);
                }
                tlsStream.Write((byte)contentType);
                tlsStream.Write(this.context.Protocol);
                tlsStream.Write((short)numArray.Length);
                tlsStream.Write(numArray);
            }
            return(tlsStream.ToArray());
        }
Пример #6
0
        private void ProcessCipherSpecV2Buffer(SecurityProtocolType protocol, byte[] buffer)
        {
            TlsStream tlsStream = new TlsStream(buffer);
            string    prefix    = protocol != SecurityProtocolType.Ssl3 ? "TLS_" : "SSL_";

            while (tlsStream.Position < tlsStream.Length)
            {
                byte num = tlsStream.ReadByte();
                if (num == (byte)0)
                {
                    int index = this.Context.SupportedCiphers.IndexOf(tlsStream.ReadInt16());
                    if (index != -1)
                    {
                        this.Context.Negotiating.Cipher = this.Context.SupportedCiphers[index];
                        break;
                    }
                }
                else
                {
                    byte[] buffer1 = new byte[2];
                    tlsStream.Read(buffer1, 0, buffer1.Length);
                    int         code        = ((int)num & (int)byte.MaxValue) << 16 | ((int)buffer1[0] & (int)byte.MaxValue) << 8 | (int)buffer1[1] & (int)byte.MaxValue;
                    CipherSuite cipherSuite = this.MapV2CipherCode(prefix, code);
                    if (cipherSuite != null)
                    {
                        this.Context.Negotiating.Cipher = cipherSuite;
                        break;
                    }
                }
            }
            if (this.Context.Negotiating == null)
            {
                throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security");
            }
        }
		public override byte[] ComputeServerRecordMAC(ContentType contentType, byte[] fragment)
		{
			HashAlgorithm	hash	= HashAlgorithm.Create(this.HashAlgorithmName);
			TlsStream		block	= new TlsStream();

			block.Write(this.Context.ServerWriteMAC);
			block.Write(this.pad1);
			if (this.Context is ClientContext)
			{
				block.Write(this.Context.ReadSequenceNumber);
			}
			else
			{
				block.Write(this.Context.WriteSequenceNumber);
			}
			block.Write((byte)contentType);
			block.Write((short)fragment.Length);
			block.Write(fragment);
			
			hash.ComputeHash(block.ToArray(), 0, (int)block.Length);

			byte[] blockHash = hash.Hash;

			block.Reset();

			block.Write(this.Context.ServerWriteMAC);
			block.Write(this.pad2);
			block.Write(blockHash);

			hash.ComputeHash(block.ToArray(), 0, (int)block.Length);

			block.Reset();

			return hash.Hash;
		}
		public override byte[] ComputeClientRecordMAC(ContentType contentType, byte[] fragment)
		{
			TlsStream	data	= new TlsStream();
			byte[]		result	= null;

			if (this.Context is ClientContext)
			{
				data.Write(this.Context.WriteSequenceNumber);
			}
			else
			{
				data.Write(this.Context.ReadSequenceNumber);
			}

			data.Write((byte)contentType);
			data.Write(this.Context.Protocol);
			data.Write((short)fragment.Length);
			data.Write(fragment);

			result = this.ClientHMAC.ComputeHash(data.ToArray());

			data.Reset();

			return result;
		}
        protected override void ProcessHandshakeMessage(TlsStream handMsg)
        {
            HandshakeType type  = (HandshakeType)handMsg.ReadByte();
            int           count = handMsg.ReadInt24();

            byte[] buffer = (byte[])null;
            if (count > 0)
            {
                buffer = new byte[count];
                handMsg.Read(buffer, 0, count);
            }
            HandshakeMessage handshakeMessage = this.createServerHandshakeMessage(type, buffer);

            handshakeMessage?.Process();
            this.Context.LastHandshakeMsg = type;
            if (handshakeMessage == null)
            {
                return;
            }
            handshakeMessage.Update();
            this.Context.HandshakeMessages.WriteByte((byte)type);
            this.Context.HandshakeMessages.WriteInt24(count);
            if (count <= 0)
            {
                return;
            }
            this.Context.HandshakeMessages.Write(buffer, 0, buffer.Length);
        }
		protected override void ProcessHandshakeMessage(TlsStream handMsg)
		{
			HandshakeType		handshakeType	= (HandshakeType)handMsg.ReadByte();
			HandshakeMessage	message			= null;

			// Read message length
			int length = handMsg.ReadInt24();

			// Read message data
			byte[] data = new byte[length];
			handMsg.Read(data, 0, length);

			// Create and process the server message
			message = this.createClientHandshakeMessage(handshakeType, data);
			message.Process();

			// Update the last handshake message
			this.Context.LastHandshakeMsg = handshakeType;

			// Update session
			if (message != null)
			{
				message.Update();
				this.Context.HandshakeMessages.WriteByte ((byte) handshakeType);
				this.Context.HandshakeMessages.WriteInt24 (length);
				this.Context.HandshakeMessages.Write (data, 0, data.Length);
			}
		}
Пример #11
0
        protected override void ProcessHandshakeMessage(TlsStream handMsg)
        {
            HandshakeType    handshakeType    = (HandshakeType)handMsg.ReadByte();
            HandshakeMessage handshakeMessage = null;
            int num = handMsg.ReadInt24();

            byte[] array = null;
            if (num > 0)
            {
                array = new byte[num];
                handMsg.Read(array, 0, num);
            }
            handshakeMessage = createServerHandshakeMessage(handshakeType, array);
            handshakeMessage?.Process();
            base.Context.LastHandshakeMsg = handshakeType;
            if (handshakeMessage != null)
            {
                handshakeMessage.Update();
                base.Context.HandshakeMessages.WriteByte((byte)handshakeType);
                base.Context.HandshakeMessages.WriteInt24(num);
                if (num > 0)
                {
                    base.Context.HandshakeMessages.Write(array, 0, array.Length);
                }
            }
        }
Пример #12
0
        public byte[] Expand(string hashName, byte[] secret, byte[] seed, int length)
        {
            int num  = (!(hashName == "MD5")) ? 20 : 16;
            int num2 = length / num;

            if (length % num > 0)
            {
                num2++;
            }
            Mono.Security.Cryptography.HMAC hMAC = new Mono.Security.Cryptography.HMAC(hashName, secret);
            TlsStream tlsStream = new TlsStream();

            byte[][] array = new byte[num2 + 1][];
            array[0] = seed;
            for (int i = 1; i <= num2; i++)
            {
                TlsStream tlsStream2 = new TlsStream();
                hMAC.TransformFinalBlock(array[i - 1], 0, array[i - 1].Length);
                array[i] = hMAC.Hash;
                tlsStream2.Write(array[i]);
                tlsStream2.Write(seed);
                hMAC.TransformFinalBlock(tlsStream2.ToArray(), 0, (int)tlsStream2.Length);
                tlsStream.Write(hMAC.Hash);
                tlsStream2.Reset();
            }
            byte[] array2 = new byte[length];
            Buffer.BlockCopy(tlsStream.ToArray(), 0, array2, 0, array2.Length);
            tlsStream.Reset();
            return(array2);
        }
Пример #13
0
        private void ProcessCipherSpecV2Buffer(SecurityProtocolType protocol, byte[] buffer)
        {
            TlsStream tlsStream = new TlsStream(buffer);
            string    prefix    = (protocol != SecurityProtocolType.Ssl3) ? "TLS_" : "SSL_";

            while (tlsStream.Position < tlsStream.Length)
            {
                byte b = tlsStream.ReadByte();
                if (b == 0)
                {
                    short code = tlsStream.ReadInt16();
                    int   num  = Context.SupportedCiphers.IndexOf(code);
                    if (num != -1)
                    {
                        Context.Negotiating.Cipher = Context.SupportedCiphers[num];
                        break;
                    }
                    continue;
                }
                byte[] array = new byte[2];
                tlsStream.Read(array, 0, array.Length);
                int         code2       = ((b & 0xFF) << 16) | ((array[0] & 0xFF) << 8) | (array[1] & 0xFF);
                CipherSuite cipherSuite = MapV2CipherCode(prefix, code2);
                if (cipherSuite == null)
                {
                    continue;
                }
                Context.Negotiating.Cipher = cipherSuite;
                break;
            }
            if (Context.Negotiating == null)
            {
                throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security");
            }
        }
Пример #14
0
        public byte[] EncodeRecord(ContentType contentType, byte[] recordData, int offset, int count)
        {
            if (context.SentConnectionEnd)
            {
                throw new TlsException(AlertDescription.InternalError, "The session is finished and it's no longer valid.");
            }
            TlsStream tlsStream = new TlsStream();
            short     num;

            for (int i = offset; i < offset + count; i += num)
            {
                num = 0;
                num = (short)((count + offset - i <= 16384) ? ((short)(count + offset - i)) : 16384);
                byte[] array = new byte[num];
                Buffer.BlockCopy(recordData, i, array, 0, num);
                if (Context.Write != null && Context.Write.Cipher != null)
                {
                    array = encryptRecordFragment(contentType, array);
                }
                tlsStream.Write((byte)contentType);
                tlsStream.Write(context.Protocol);
                tlsStream.Write((short)array.Length);
                tlsStream.Write(array);
            }
            return(tlsStream.ToArray());
        }
Пример #15
0
        private byte[] prf(byte[] secret, string label, byte[] random)
        {
            HashAlgorithm md5 = MD5.Create();
            HashAlgorithm sha = SHA1.Create();

            // Compute SHA hash
            TlsStream block = new TlsStream();

            block.Write(Encoding.ASCII.GetBytes(label));
            block.Write(secret);
            block.Write(random);

            byte[] shaHash = sha.ComputeHash(block.ToArray(), 0, (int)block.Length);

            block.Reset();

            // Compute MD5 hash
            block.Write(secret);
            block.Write(shaHash);

            byte[] result = md5.ComputeHash(block.ToArray(), 0, (int)block.Length);

            // Free resources
            block.Reset();

            return(result);
        }
Пример #16
0
        protected override void ProcessHandshakeMessage(TlsStream handMsg)
        {
            HandshakeType    handshakeType = (HandshakeType)handMsg.ReadByte();
            HandshakeMessage message       = null;

            // Read message length
            int length = handMsg.ReadInt24();

            // Read message data
            byte[] data = new byte[length];
            handMsg.Read(data, 0, length);

            // Create and process the server message
            message = this.createClientHandshakeMessage(handshakeType, data);
            message.Process();

            // Update the last handshake message
            this.Context.LastHandshakeMsg = handshakeType;

            // Update session
            if (message != null)
            {
                message.Update();
                this.Context.HandshakeMessages.WriteByte((byte)handshakeType);
                this.Context.HandshakeMessages.WriteInt24(length);
                this.Context.HandshakeMessages.Write(data, 0, data.Length);
            }
        }
        public override void ComputeKeys()
        {
            // Create keyblock
            TlsStream keyBlock = new TlsStream(this.PRF(this.Context.MasterSecret, "key expansion", this.Context.RandomSC, this.KeyBlockSize));

            this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize);
            this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize);
            this.Context.ClientWriteKey             = keyBlock.ReadBytes(this.KeyMaterialSize);
            this.Context.ServerWriteKey             = keyBlock.ReadBytes(this.KeyMaterialSize);

            if (this.IvSize != 0)
            {
                this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
                this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
            }
            else
            {
                this.Context.ClientWriteIV = CipherSuite.EmptyArray;
                this.Context.ServerWriteIV = CipherSuite.EmptyArray;
            }

            DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
            DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey);
            DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV);
            DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC);
            DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey);
            DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV);
            DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC);

            ClientSessionCache.SetContextInCache(this.Context);
            // Clear no more needed data
            keyBlock.Reset();
        }
Пример #18
0
        public byte[] Expand(HashAlgorithm hash, byte[] secret, byte[] seed, int length)
        {
            int hashLength = hash.HashSize / 8;
            int iterations = (int)(length / hashLength);

            if ((length % hashLength) > 0)
            {
                iterations++;
            }

            M.HMAC    hmac    = new M.HMAC(hash, secret);
            TlsStream resMacs = new TlsStream();

            byte[][] hmacs = new byte[iterations + 1][];
            hmacs[0] = seed;
            for (int i = 1; i <= iterations; i++)
            {
                TlsStream hcseed = new TlsStream();
                hmac.TransformFinalBlock(hmacs[i - 1], 0, hmacs[i - 1].Length);
                hmacs[i] = hmac.Hash;
                hcseed.Write(hmacs[i]);
                hcseed.Write(seed);
                hmac.TransformFinalBlock(hcseed.ToArray(), 0, (int)hcseed.Length);
                resMacs.Write(hmac.Hash);
                hcseed.Reset();
            }

            byte[] res = new byte[length];

            Buffer.BlockCopy(resMacs.ToArray(), 0, res, 0, res.Length);

            resMacs.Reset();

            return(res);
        }
Пример #19
0
        public override void ComputeKeys()
        {
            // Compute KeyBlock
            TlsStream tmp = new TlsStream();

            char labelChar = 'A';
            int  count     = 1;

            while (tmp.Length < this.KeyBlockSize)
            {
                string label = String.Empty;

                for (int i = 0; i < count; i++)
                {
                    label += labelChar.ToString();
                }

                byte[] block = this.prf(this.Context.MasterSecret, label.ToString(), this.Context.RandomSC);

                int size = (tmp.Length + block.Length) > this.KeyBlockSize ? (this.KeyBlockSize - (int)tmp.Length) : block.Length;

                tmp.Write(block, 0, size);

                labelChar++;
                count++;
            }

            // Create keyblock
            TlsStream keyBlock = new TlsStream(tmp.ToArray());

            this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize);
            this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize);
            this.Context.ClientWriteKey             = keyBlock.ReadBytes(this.KeyMaterialSize);
            this.Context.ServerWriteKey             = keyBlock.ReadBytes(this.KeyMaterialSize);

            if (this.IvSize != 0)
            {
                this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
                this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
            }
            else
            {
                this.Context.ClientWriteIV = CipherSuite.EmptyArray;
                this.Context.ServerWriteIV = CipherSuite.EmptyArray;
            }

            DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
            DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey);
            DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV);
            DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC);
            DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey);
            DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV);
            DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC);

            ClientSessionCache.SetContextInCache(this.Context);
            // Clear no more needed data
            keyBlock.Reset();
            tmp.Reset();
        }
Пример #20
0
        public override void ComputeMasterSecret(byte[] preMasterSecret)
        {
            TlsStream tlsStream = new TlsStream();

            tlsStream.Write(prf(preMasterSecret, "A", base.Context.RandomCS));
            tlsStream.Write(prf(preMasterSecret, "BB", base.Context.RandomCS));
            tlsStream.Write(prf(preMasterSecret, "CCC", base.Context.RandomCS));
            base.Context.MasterSecret = tlsStream.ToArray();
        }
Пример #21
0
        public byte[] PRF(byte[] secret, string label, byte[] data, int length)
        {
            /* Secret Length calc exmplain from the RFC2246. Section 5
             *
             * S1 and S2 are the two halves of the secret and each is the same
             * length. S1 is taken from the first half of the secret, S2 from the
             * second half. Their length is created by rounding up the length of the
             * overall secret divided by two; thus, if the original secret is an odd
             * number of bytes long, the last byte of S1 will be the same as the
             * first byte of S2.
             */

            // split secret in 2
            var secretLen = secret.Length >> 1;

            // rounding up
            if ((secret.Length & 0x1) == 0x1)
            {
                secretLen++;
            }

            // Seed
            var seedStream = new TlsStream();

            seedStream.Write(Encoding.ASCII.GetBytes(label));
            seedStream.Write(data);
            var seed = seedStream.ToArray();

            seedStream.Reset();

            // Secret 1
            var secret1 = new byte[secretLen];

            Buffer.BlockCopy(secret, 0, secret1, 0, secretLen);

            // Secret2
            var secret2 = new byte[secretLen];

            Buffer.BlockCopy(secret, secret.Length - secretLen, secret2, 0, secretLen);

            // Secret 1 processing
            var p_md5 = Expand(MD5.Create(), secret1, seed, length);

            // Secret 2 processing
            var p_sha = Expand(SHA1.Create(), secret2, seed, length);

            // Perfor XOR of both results
            var masterSecret = new byte[length];

            for (var i = 0; i < masterSecret.Length; i++)
            {
                masterSecret[i] = (byte)(p_md5[i] ^ p_sha[i]);
            }

            return(masterSecret);
        }
Пример #22
0
 public virtual void Clear()
 {
     compressionMethod = SecurityCompressionType.None;
     serverSettings    = new TlsServerSettings();
     clientSettings    = new TlsClientSettings();
     handshakeMessages = new TlsStream();
     sessionId         = null;
     handshakeState    = HandshakeState.None;
     ClearKeyInfo();
 }
Пример #23
0
 public virtual void Clear()
 {
     this.compressionMethod = SecurityCompressionType.None;
     this.serverSettings    = new TlsServerSettings();
     this.clientSettings    = new TlsClientSettings();
     this.handshakeMessages = new TlsStream();
     this.sessionId         = (byte[])null;
     this.handshakeState    = HandshakeState.None;
     this.ClearKeyInfo();
 }
Пример #24
0
        public byte[] EncodeRecord(
            ContentType contentType,
            byte[]          recordData,
            int offset,
            int count)
        {
            if (this.context.SentConnectionEnd)
            {
                throw new TlsException(
                          AlertDescription.InternalError,
                          "The session is finished and it's no longer valid.");
            }

            TlsStream record = new TlsStream();

            int position = offset;

            while (position < (offset + count))
            {
                short  fragmentLength = 0;
                byte[] fragment;

                if ((count + offset - position) > Context.MAX_FRAGMENT_SIZE)
                {
                    fragmentLength = Context.MAX_FRAGMENT_SIZE;
                }
                else
                {
                    fragmentLength = (short)(count + offset - position);
                }

                // Fill the fragment data
                fragment = new byte[fragmentLength];
                Buffer.BlockCopy(recordData, position, fragment, 0, fragmentLength);

                if ((this.Context.Write != null) && (this.Context.Write.Cipher != null))
                {
                    // Encrypt fragment
                    fragment = this.encryptRecordFragment(contentType, fragment);
                }

                // Write tls message
                record.Write((byte)contentType);
                record.Write(this.context.Protocol);
                record.Write((short)fragment.Length);
                record.Write(fragment);

                DebugHelper.WriteLine("Record data", fragment);

                // Update buffer position
                position += fragmentLength;
            }

            return(record.ToArray());
        }
Пример #25
0
 public Context(SecurityProtocolType securityProtocolType)
 {
     this.SecurityProtocol  = securityProtocolType;
     this.compressionMethod = SecurityCompressionType.None;
     this.serverSettings    = new TlsServerSettings();
     this.clientSettings    = new TlsClientSettings();
     this.handshakeMessages = new TlsStream();
     this.sessionId         = null;
     this.handshakeState    = HandshakeState.None;
     this.random            = RandomNumberGenerator.Create();
 }
Пример #26
0
        public override void ComputeMasterSecret(byte[] preMasterSecret)
        {
            TlsStream masterSecret = new TlsStream();

            masterSecret.Write(this.prf(preMasterSecret, "A", this.Context.RandomCS));
            masterSecret.Write(this.prf(preMasterSecret, "BB", this.Context.RandomCS));
            masterSecret.Write(this.prf(preMasterSecret, "CCC", this.Context.RandomCS));

            this.Context.MasterSecret = masterSecret.ToArray();

            DebugHelper.WriteLine(">>>> MasterSecret", this.Context.MasterSecret);
        }
Пример #27
0
        private byte[] prf(byte[] secret, string label, byte[] random)
        {
            HashAlgorithm hashAlgorithm  = MD5.Create();
            HashAlgorithm hashAlgorithm2 = SHA1.Create();
            TlsStream     tlsStream      = new TlsStream();

            tlsStream.Write(Encoding.ASCII.GetBytes(label));
            tlsStream.Write(secret);
            tlsStream.Write(random);
            byte[] buffer = hashAlgorithm2.ComputeHash(tlsStream.ToArray(), 0, (int)tlsStream.Length);
            tlsStream.Reset();
            tlsStream.Write(secret);
            tlsStream.Write(buffer);
            byte[] result = hashAlgorithm.ComputeHash(tlsStream.ToArray(), 0, (int)tlsStream.Length);
            tlsStream.Reset();
            return(result);
        }
Пример #28
0
        public override void ComputeKeys()
        {
            TlsStream tlsStream = new TlsStream(PRF(base.Context.MasterSecret, "key expansion", base.Context.RandomSC, base.KeyBlockSize));

            base.Context.Negotiating.ClientWriteMAC = tlsStream.ReadBytes(base.HashSize);
            base.Context.Negotiating.ServerWriteMAC = tlsStream.ReadBytes(base.HashSize);
            base.Context.ClientWriteKey             = tlsStream.ReadBytes(base.KeyMaterialSize);
            base.Context.ServerWriteKey             = tlsStream.ReadBytes(base.KeyMaterialSize);
            if (!base.IsExportable)
            {
                if (base.IvSize != 0)
                {
                    base.Context.ClientWriteIV = tlsStream.ReadBytes(base.IvSize);
                    base.Context.ServerWriteIV = tlsStream.ReadBytes(base.IvSize);
                }
                else
                {
                    base.Context.ClientWriteIV = CipherSuite.EmptyArray;
                    base.Context.ServerWriteIV = CipherSuite.EmptyArray;
                }
            }
            else
            {
                byte[] clientWriteKey = PRF(base.Context.ClientWriteKey, "client write key", base.Context.RandomCS, base.ExpandedKeyMaterialSize);
                byte[] serverWriteKey = PRF(base.Context.ServerWriteKey, "server write key", base.Context.RandomCS, base.ExpandedKeyMaterialSize);
                base.Context.ClientWriteKey = clientWriteKey;
                base.Context.ServerWriteKey = serverWriteKey;
                if (base.IvSize > 0)
                {
                    byte[] src = PRF(CipherSuite.EmptyArray, "IV block", base.Context.RandomCS, base.IvSize * 2);
                    base.Context.ClientWriteIV = new byte[base.IvSize];
                    Buffer.BlockCopy(src, 0, base.Context.ClientWriteIV, 0, base.Context.ClientWriteIV.Length);
                    base.Context.ServerWriteIV = new byte[base.IvSize];
                    Buffer.BlockCopy(src, base.IvSize, base.Context.ServerWriteIV, 0, base.Context.ServerWriteIV.Length);
                }
                else
                {
                    base.Context.ClientWriteIV = CipherSuite.EmptyArray;
                    base.Context.ServerWriteIV = CipherSuite.EmptyArray;
                }
            }
            ClientSessionCache.SetContextInCache(base.Context);
            tlsStream.Reset();
        }
Пример #29
0
        public override void ComputeKeys()
        {
            TlsStream tlsStream = new TlsStream(this.PRF(this.Context.MasterSecret, "key expansion", this.Context.RandomSC, this.KeyBlockSize));

            this.Context.Negotiating.ClientWriteMAC = tlsStream.ReadBytes(this.HashSize);
            this.Context.Negotiating.ServerWriteMAC = tlsStream.ReadBytes(this.HashSize);
            this.Context.ClientWriteKey             = tlsStream.ReadBytes((int)this.KeyMaterialSize);
            this.Context.ServerWriteKey             = tlsStream.ReadBytes((int)this.KeyMaterialSize);
            if (!this.IsExportable)
            {
                if (this.IvSize != (byte)0)
                {
                    this.Context.ClientWriteIV = tlsStream.ReadBytes((int)this.IvSize);
                    this.Context.ServerWriteIV = tlsStream.ReadBytes((int)this.IvSize);
                }
                else
                {
                    this.Context.ClientWriteIV = CipherSuite.EmptyArray;
                    this.Context.ServerWriteIV = CipherSuite.EmptyArray;
                }
            }
            else
            {
                byte[] numArray1 = this.PRF(this.Context.ClientWriteKey, "client write key", this.Context.RandomCS, (int)this.ExpandedKeyMaterialSize);
                byte[] numArray2 = this.PRF(this.Context.ServerWriteKey, "server write key", this.Context.RandomCS, (int)this.ExpandedKeyMaterialSize);
                this.Context.ClientWriteKey = numArray1;
                this.Context.ServerWriteKey = numArray2;
                if (this.IvSize > (byte)0)
                {
                    byte[] numArray3 = this.PRF(CipherSuite.EmptyArray, "IV block", this.Context.RandomCS, (int)this.IvSize * 2);
                    this.Context.ClientWriteIV = new byte[(int)this.IvSize];
                    Buffer.BlockCopy((Array)numArray3, 0, (Array)this.Context.ClientWriteIV, 0, this.Context.ClientWriteIV.Length);
                    this.Context.ServerWriteIV = new byte[(int)this.IvSize];
                    Buffer.BlockCopy((Array)numArray3, (int)this.IvSize, (Array)this.Context.ServerWriteIV, 0, this.Context.ServerWriteIV.Length);
                }
                else
                {
                    this.Context.ClientWriteIV = CipherSuite.EmptyArray;
                    this.Context.ServerWriteIV = CipherSuite.EmptyArray;
                }
            }
            ClientSessionCache.SetContextInCache(this.Context);
            tlsStream.Reset();
        }
Пример #30
0
        private void ProcessCipherSpecV2Buffer(SecurityProtocolType protocol, byte[] buffer)
        {
            TlsStream codes = new TlsStream(buffer);

            string prefix = (protocol == SecurityProtocolType.Ssl3) ? "SSL_" : "TLS_";

            while (codes.Position < codes.Length)
            {
                byte check = codes.ReadByte();

                if (check == 0)
                {
                    // SSL/TLS cipher spec
                    short code  = codes.ReadInt16();
                    int   index = this.Context.SupportedCiphers.IndexOf(code);
                    if (index != -1)
                    {
                        this.Context.Negotiating.Cipher = this.Context.SupportedCiphers[index];
                        break;
                    }
                }
                else
                {
                    byte[] tmp = new byte[2];
                    codes.Read(tmp, 0, tmp.Length);

                    int         tmpCode = ((check & 0xff) << 16) | ((tmp[0] & 0xff) << 8) | (tmp[1] & 0xff);
                    CipherSuite cipher  = this.MapV2CipherCode(prefix, tmpCode);

                    if (cipher != null)
                    {
                        this.Context.Negotiating.Cipher = cipher;
                        break;
                    }
                }
            }

            if (this.Context.Negotiating == null)
            {
                throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security");
            }
        }
Пример #31
0
        protected override void ProcessHandshakeMessage(TlsStream handMsg)
        {
            HandshakeType    handshakeType = (HandshakeType)handMsg.ReadByte();
            HandshakeMessage message       = null;

            DebugHelper.WriteLine(">>>> Processing Handshake record ({0})", handshakeType);

            // Read message length
            int length = handMsg.ReadInt24();

            // Read message data
            byte[] data = null;
            if (length > 0)
            {
                data = new byte[length];
                handMsg.Read(data, 0, length);
            }

            // Create and process the server message
            message = this.createServerHandshakeMessage(handshakeType, data);
            if (message != null)
            {
                message.Process();
            }

            // Update the last handshake message
            this.Context.LastHandshakeMsg = handshakeType;

            // Update session
            if (message != null)
            {
                message.Update();
                this.Context.HandshakeMessages.WriteByte((byte)handshakeType);
                this.Context.HandshakeMessages.WriteInt24(length);
                if (length > 0)
                {
                    this.Context.HandshakeMessages.Write(data, 0, data.Length);
                }
            }
        }
Пример #32
0
		public byte[] Expand(string hashName, byte[] secret, byte[] seed, int length)
		{
			int hashLength	= hashName == "MD5" ? 16 : 20;
			int	iterations	= (int)(length / hashLength);
			if ((length % hashLength) > 0)
			{
				iterations++;
			}
			
			M.HMAC		hmac	= new M.HMAC(hashName, secret);
			TlsStream	resMacs	= new TlsStream();
			
			byte[][] hmacs = new byte[iterations + 1][];
			hmacs[0] = seed;
			for (int i = 1; i <= iterations; i++)
			{				
				TlsStream hcseed = new TlsStream();
				hmac.TransformFinalBlock(hmacs[i-1], 0, hmacs[i-1].Length);
				hmacs[i] = hmac.Hash;
				hcseed.Write(hmacs[i]);
				hcseed.Write(seed);
				hmac.TransformFinalBlock(hcseed.ToArray(), 0, (int)hcseed.Length);
				resMacs.Write(hmac.Hash);
				hcseed.Reset();
			}

			byte[] res = new byte[length];
			
			Buffer.BlockCopy(resMacs.ToArray(), 0, res, 0, res.Length);

			resMacs.Reset();

			return res;
		}
Пример #33
0
		public override void ComputeMasterSecret(byte[] preMasterSecret)
		{
			TlsStream masterSecret = new TlsStream();

			masterSecret.Write(this.prf(preMasterSecret, "A", this.Context.RandomCS));
			masterSecret.Write(this.prf(preMasterSecret, "BB", this.Context.RandomCS));
			masterSecret.Write(this.prf(preMasterSecret, "CCC", this.Context.RandomCS));

			this.Context.MasterSecret = masterSecret.ToArray();

			DebugHelper.WriteLine(">>>> MasterSecret", this.Context.MasterSecret);
		}
Пример #34
0
		public byte[] PRF(byte[] secret, string label, byte[] data, int length)
		{
			/* Secret Length calc exmplain from the RFC2246. Section 5
			 * 
			 * S1 and S2 are the two halves of the secret and each is the same
			 * length. S1 is taken from the first half of the secret, S2 from the
			 * second half. Their length is created by rounding up the length of the
			 * overall secret divided by two; thus, if the original secret is an odd
			 * number of bytes long, the last byte of S1 will be the same as the
			 * first byte of S2.
			 */

			// split secret in 2
			int secretLen = secret.Length >> 1;
			// rounding up
			if ((secret.Length & 0x1) == 0x1)
				secretLen++;

			// Seed
			TlsStream seedStream = new TlsStream();
			seedStream.Write(Encoding.ASCII.GetBytes(label));
			seedStream.Write(data);
			byte[] seed = seedStream.ToArray();
			seedStream.Reset();

			// Secret 1
			byte[] secret1 = new byte[secretLen];
			Buffer.BlockCopy(secret, 0, secret1, 0, secretLen);

			// Secret2
			byte[] secret2 = new byte[secretLen];
			Buffer.BlockCopy(secret, (secret.Length - secretLen), secret2, 0, secretLen);

			// Secret 1 processing
			byte[] p_md5 = Expand("MD5", secret1, seed, length);

			// Secret 2 processing
			byte[] p_sha = Expand("SHA1", secret2, seed, length);

			// Perfor XOR of both results
			byte[] masterSecret = new byte[length];
			for (int i = 0; i < masterSecret.Length; i++)
			{
				masterSecret[i] = (byte)(p_md5[i] ^ p_sha[i]);
			}

			return masterSecret;
		}
Пример #35
0
		public byte[] CreatePremasterSecret()
		{
			TlsStream		stream	= new TlsStream();
			ClientContext	context = (ClientContext)this.context;
			
			// Write protocol version
			// We need to send here the protocol version used in 
			// the ClientHello message, that can be different than the actual
			// protocol version
			stream.Write(context.ClientHelloProtocol);

			// Generate random bytes
			stream.Write(this.context.GetSecureRandomBytes(46));

			byte[] preMasterSecret = stream.ToArray();

			stream.Reset();

			return preMasterSecret;
		}
Пример #36
0
 protected abstract void ProcessHandshakeMessage(TlsStream handMsg);
		protected override void ProcessAsTls1()
		{
#warning "Client certificate selection is unfinished"
			ClientContext context = (ClientContext)this.Context;
			string msg = "Client certificate requested by the server and no client certificate specified.";

			if (context.ClientSettings.Certificates == null ||
				context.ClientSettings.Certificates.Count == 0)
			{
				throw new TlsException(AlertDescription.UserCancelled, msg);
			}
			
			// Select a valid certificate
			X509Certificate clientCert = this.Context.ClientSettings.Certificates[0];

			clientCert = context.SslStream.RaiseClientCertificateSelection(
				this.Context.ClientSettings.Certificates,
				new X509Certificate(this.Context.ServerSettings.Certificates[0].RawData),
				this.Context.ClientSettings.TargetHost,
				null);

			if (clientCert == null)
			{
				throw new TlsException(AlertDescription.UserCancelled, msg);
			}

			// Update the selected client certificate
			context.ClientSettings.ClientCertificate = clientCert;

			// Write client certificates information to a stream
			TlsStream stream = new TlsStream();

			stream.WriteInt24(clientCert.GetRawCertData().Length);
			stream.Write(clientCert.GetRawCertData());

			// Compose the message
			this.WriteInt24((int)stream.Length);
			this.Write(stream.ToArray());
		}
Пример #38
0
		public override void ComputeKeys()
		{
			// Create keyblock
			TlsStream keyBlock = new TlsStream(
				this.PRF(
				this.Context.MasterSecret, 
				"key expansion",
				this.Context.RandomSC,
				this.KeyBlockSize));

			this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize);
			this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize);
			this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);
			this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);

			if (!this.IsExportable)
			{
				if (this.IvSize != 0)
				{
					this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
					this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
				}
				else
				{
					this.Context.ClientWriteIV = CipherSuite.EmptyArray;
					this.Context.ServerWriteIV = CipherSuite.EmptyArray;
				}
			}
			else
			{
				// Generate final write keys
				byte[] finalClientWriteKey	= PRF(this.Context.ClientWriteKey, "client write key", this.Context.RandomCS, this.ExpandedKeyMaterialSize);
				byte[] finalServerWriteKey	= PRF(this.Context.ServerWriteKey, "server write key", this.Context.RandomCS, this.ExpandedKeyMaterialSize);
				
				this.Context.ClientWriteKey	= finalClientWriteKey;
				this.Context.ServerWriteKey	= finalServerWriteKey;

				if (this.IvSize > 0) 
				{
					// Generate IV block
					byte[] ivBlock = PRF(CipherSuite.EmptyArray, "IV block", this.Context.RandomCS, this.IvSize*2);

					// Generate IV keys
					this.Context.ClientWriteIV = new byte[this.IvSize];				
					Buffer.BlockCopy(ivBlock, 0, this.Context.ClientWriteIV, 0, this.Context.ClientWriteIV.Length);

					this.Context.ServerWriteIV = new byte[this.IvSize];
					Buffer.BlockCopy(ivBlock, this.IvSize, this.Context.ServerWriteIV, 0, this.Context.ServerWriteIV.Length);
				}
				else 
				{
					this.Context.ClientWriteIV = CipherSuite.EmptyArray;
					this.Context.ServerWriteIV = CipherSuite.EmptyArray;
				}
			}

			DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
			DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey);
			DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV);
			DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC);
			DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey);
			DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV);
			DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC);

			ClientSessionCache.SetContextInCache (this.Context);
			// Clear no more needed data
			keyBlock.Reset();
		}
		private void SendCertificates ()
		{
			TlsStream chain = new TlsStream ();

			X509Certificate currentCert = this.ClientCertificate;
			while (currentCert != null) {
				byte[] rawCert = currentCert.GetRawCertData ();
				chain.WriteInt24 (rawCert.Length);
				chain.Write(rawCert);
				currentCert = FindParentCertificate (currentCert);
			}
			this.WriteInt24 ((int)chain.Length);
			this.Write (chain.ToArray ());
		}
		protected abstract void ProcessHandshakeMessage(TlsStream handMsg);
Пример #41
0
        public override void ComputeKeys()
        {
            // Compute KeyBlock
            TlsStream tmp = new TlsStream();

            char labelChar = 'A';
            int  count     = 1;

            while (tmp.Length < this.KeyBlockSize)
            {
                string label = String.Empty;

                for (int i = 0; i < count; i++)
                {
                    label += labelChar.ToString();
                }

                byte[] block = this.prf(this.Context.MasterSecret, label.ToString(), this.Context.RandomSC);

                int size = (tmp.Length + block.Length) > this.KeyBlockSize ? (this.KeyBlockSize - (int)tmp.Length) : block.Length;

                tmp.Write(block, 0, size);

                labelChar++;
                count++;
            }

            // Create keyblock
            TlsStream keyBlock = new TlsStream(tmp.ToArray());

            this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize);
            this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize);
            this.Context.ClientWriteKey             = keyBlock.ReadBytes(this.KeyMaterialSize);
            this.Context.ServerWriteKey             = keyBlock.ReadBytes(this.KeyMaterialSize);

            if (!this.IsExportable)
            {
                if (this.IvSize != 0)
                {
                    this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
                    this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
                }
                else
                {
                    this.Context.ClientWriteIV = CipherSuite.EmptyArray;
                    this.Context.ServerWriteIV = CipherSuite.EmptyArray;
                }
            }
            else
            {
                HashAlgorithm md5 = MD5.Create();

                int    keySize = (md5.HashSize >> 3);              //in bytes not bits
                byte[] temp    = new byte [keySize];

                // Generate final write keys
                md5.TransformBlock(this.Context.ClientWriteKey, 0, this.Context.ClientWriteKey.Length, temp, 0);
                md5.TransformFinalBlock(this.Context.RandomCS, 0, this.Context.RandomCS.Length);
                byte[] finalClientWriteKey = new byte[this.ExpandedKeyMaterialSize];
                Buffer.BlockCopy(md5.Hash, 0, finalClientWriteKey, 0, this.ExpandedKeyMaterialSize);

                md5.Initialize();
                md5.TransformBlock(this.Context.ServerWriteKey, 0, this.Context.ServerWriteKey.Length, temp, 0);
                md5.TransformFinalBlock(this.Context.RandomSC, 0, this.Context.RandomSC.Length);
                byte[] finalServerWriteKey = new byte[this.ExpandedKeyMaterialSize];
                Buffer.BlockCopy(md5.Hash, 0, finalServerWriteKey, 0, this.ExpandedKeyMaterialSize);

                this.Context.ClientWriteKey = finalClientWriteKey;
                this.Context.ServerWriteKey = finalServerWriteKey;

                // Generate IV keys
                if (this.IvSize > 0)
                {
                    md5.Initialize();
                    temp = md5.ComputeHash(this.Context.RandomCS, 0, this.Context.RandomCS.Length);
                    this.Context.ClientWriteIV = new byte[this.IvSize];
                    Buffer.BlockCopy(temp, 0, this.Context.ClientWriteIV, 0, this.IvSize);

                    md5.Initialize();
                    temp = md5.ComputeHash(this.Context.RandomSC, 0, this.Context.RandomSC.Length);
                    this.Context.ServerWriteIV = new byte[this.IvSize];
                    Buffer.BlockCopy(temp, 0, this.Context.ServerWriteIV, 0, this.IvSize);
                }
                else
                {
                    this.Context.ClientWriteIV = CipherSuite.EmptyArray;
                    this.Context.ServerWriteIV = CipherSuite.EmptyArray;
                }
            }

            DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
            DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey);
            DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV);
            DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC);
            DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey);
            DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV);
            DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC);

            ClientSessionCache.SetContextInCache(this.Context);
            // Clear no more needed data
            keyBlock.Reset();
            tmp.Reset();
        }
		private void InternalReceiveRecordCallback(IAsyncResult asyncResult)
		{
			ReceiveRecordAsyncResult internalResult = asyncResult.AsyncState as ReceiveRecordAsyncResult;
			Stream record = internalResult.Record;

			try
			{
				
				int bytesRead = internalResult.Record.EndRead(asyncResult);

				//We're at the end of the stream. Time to bail.
				if (bytesRead == 0)
				{
					internalResult.SetComplete((byte[])null);
					return;
				}

				// Try to read the Record Content Type
				int type = internalResult.InitialBuffer[0];

				// Set last handshake message received to None
				this.context.LastHandshakeMsg = HandshakeType.ClientHello;

				ContentType	contentType	= (ContentType)type;
				byte[] buffer = this.ReadRecordBuffer(type, record);
				if (buffer == null)
				{
					// record incomplete (at the moment)
					internalResult.SetComplete((byte[])null);
					return;
				}

				// Decrypt message contents if needed
				if (contentType == ContentType.Alert && buffer.Length == 2)
				{
				}
				else if ((this.Context.Read != null) && (this.Context.Read.Cipher != null))
				{
					buffer = this.decryptRecordFragment (contentType, buffer);
					DebugHelper.WriteLine ("Decrypted record data", buffer);
				}

				// Process record
				switch (contentType)
				{
					case ContentType.Alert:
						this.ProcessAlert((AlertLevel)buffer [0], (AlertDescription)buffer [1]);
						if (record.CanSeek) 
						{
							// don't reprocess that memory block
							record.SetLength (0); 
						}
						buffer = null;
						break;

					case ContentType.ChangeCipherSpec:
						this.ProcessChangeCipherSpec();
						break;

					case ContentType.ApplicationData:
						break;

					case ContentType.Handshake:
						TlsStream message = new TlsStream (buffer);
						while (!message.EOF)
						{
							this.ProcessHandshakeMessage(message);
						}
						break;

					case (ContentType)0x80:
						this.context.HandshakeMessages.Write (buffer);
						break;

					default:
						throw new TlsException(
							AlertDescription.UnexpectedMessage,
							"Unknown record received from server.");
				}

				internalResult.SetComplete(buffer);
			}
			catch (Exception ex)
			{
				internalResult.SetComplete(ex);
			}

		}
Пример #43
0
		public override void ComputeKeys()
		{
			// Compute KeyBlock
			TlsStream tmp = new TlsStream();
			
			char	labelChar	= 'A';
			int		count		= 1;

			while (tmp.Length < this.KeyBlockSize)
			{
				string label = String.Empty;

				for (int i = 0; i < count; i++)
				{
					label += labelChar.ToString();
				}
						
				byte[] block = this.prf(this.Context.MasterSecret, label.ToString(), this.Context.RandomSC);

				int size = (tmp.Length + block.Length) > this.KeyBlockSize ? (this.KeyBlockSize - (int)tmp.Length) : block.Length;
				
				tmp.Write(block, 0, size);

				labelChar++;
				count++;
			}
			
			// Create keyblock
			TlsStream keyBlock = new TlsStream(tmp.ToArray());			
			
			this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize);
			this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize);
			this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);
			this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);

			if (!this.IsExportable)
			{
				if (this.IvSize != 0)
				{
					this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
					this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
				}
				else
				{
					this.Context.ClientWriteIV = CipherSuite.EmptyArray;
					this.Context.ServerWriteIV = CipherSuite.EmptyArray;
				}
			}
			else
			{
				HashAlgorithm md5 = MD5.Create();

				int keySize = (md5.HashSize >> 3); //in bytes not bits
				byte[] temp = new byte [keySize];

				// Generate final write keys
				md5.TransformBlock(this.Context.ClientWriteKey, 0, this.Context.ClientWriteKey.Length, temp, 0);
				md5.TransformFinalBlock(this.Context.RandomCS, 0, this.Context.RandomCS.Length);
				byte[] finalClientWriteKey = new byte[this.ExpandedKeyMaterialSize];
				Buffer.BlockCopy(md5.Hash, 0, finalClientWriteKey, 0, this.ExpandedKeyMaterialSize);

				md5.Initialize();
				md5.TransformBlock(this.Context.ServerWriteKey, 0, this.Context.ServerWriteKey.Length, temp, 0);
				md5.TransformFinalBlock(this.Context.RandomSC, 0, this.Context.RandomSC.Length);
				byte[] finalServerWriteKey = new byte[this.ExpandedKeyMaterialSize];
				Buffer.BlockCopy(md5.Hash, 0, finalServerWriteKey, 0, this.ExpandedKeyMaterialSize);
				
				this.Context.ClientWriteKey = finalClientWriteKey;
				this.Context.ServerWriteKey = finalServerWriteKey;

				// Generate IV keys
				if (this.IvSize > 0) 
				{
					md5.Initialize();
					temp = md5.ComputeHash(this.Context.RandomCS, 0, this.Context.RandomCS.Length);
					this.Context.ClientWriteIV = new byte[this.IvSize];
					Buffer.BlockCopy(temp, 0, this.Context.ClientWriteIV, 0, this.IvSize);

					md5.Initialize();
					temp = md5.ComputeHash(this.Context.RandomSC, 0, this.Context.RandomSC.Length);
					this.Context.ServerWriteIV = new byte[this.IvSize];
					Buffer.BlockCopy(temp, 0, this.Context.ServerWriteIV, 0, this.IvSize);
				}
				else 
				{
					this.Context.ClientWriteIV = CipherSuite.EmptyArray;
					this.Context.ServerWriteIV = CipherSuite.EmptyArray;
				}
			}

			DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
			DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey);
			DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV);
			DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC);
			DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey);
			DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV);
			DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC);

			ClientSessionCache.SetContextInCache (this.Context);
			// Clear no more needed data
			keyBlock.Reset();
			tmp.Reset();
		}
Пример #44
0
		public override void ComputeKeys()
		{
			// Create keyblock
			TlsStream keyBlock = new TlsStream(
				this.PRF(
				this.Context.MasterSecret, 
				"key expansion",
				this.Context.RandomSC,
				this.KeyBlockSize));

			this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize);
			this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize);
			this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);
			this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);

			if (this.IvSize != 0)
			{
				this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
				this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
			}
			else
			{
				this.Context.ClientWriteIV = CipherSuite.EmptyArray;
				this.Context.ServerWriteIV = CipherSuite.EmptyArray;
			}

			DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
			DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey);
			DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV);
			DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC);
			DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey);
			DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV);
			DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC);

			ClientSessionCache.SetContextInCache (this.Context);
			// Clear no more needed data
			keyBlock.Reset();
		}
Пример #45
0
		public override void ComputeKeys()
		{
			// Compute KeyBlock
			TlsStream tmp = new TlsStream();
			
			char	labelChar	= 'A';
			int		count		= 1;

			while (tmp.Length < this.KeyBlockSize)
			{
				string label = String.Empty;

				for (int i = 0; i < count; i++)
				{
					label += labelChar.ToString();
				}
						
				byte[] block = this.prf(this.Context.MasterSecret, label.ToString(), this.Context.RandomSC);

				int size = (tmp.Length + block.Length) > this.KeyBlockSize ? (this.KeyBlockSize - (int)tmp.Length) : block.Length;
				
				tmp.Write(block, 0, size);

				labelChar++;
				count++;
			}
			
			// Create keyblock
			TlsStream keyBlock = new TlsStream(tmp.ToArray());			
			
			this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize);
			this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize);
			this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);
			this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);

			if (this.IvSize != 0)
			{
				this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
				this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
			}
			else
			{
				this.Context.ClientWriteIV = CipherSuite.EmptyArray;
				this.Context.ServerWriteIV = CipherSuite.EmptyArray;
			}

			DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
			DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey);
			DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV);
			DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC);
			DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey);
			DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV);
			DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC);

			ClientSessionCache.SetContextInCache (this.Context);
			// Clear no more needed data
			keyBlock.Reset();
			tmp.Reset();
		}
Пример #46
0
        private void InternalReceiveRecordCallback(IAsyncResult asyncResult)
        {
            ReceiveRecordAsyncResult internalResult = asyncResult.AsyncState as ReceiveRecordAsyncResult;
            Stream record = internalResult.Record;

            try
            {
                int bytesRead = internalResult.Record.EndRead(asyncResult);

                //We're at the end of the stream. Time to bail.
                if (bytesRead == 0)
                {
                    internalResult.SetComplete((byte[])null);
                    return;
                }

                // Try to read the Record Content Type
                int type = internalResult.InitialBuffer[0];

                // Set last handshake message received to None
                this.context.LastHandshakeMsg = HandshakeType.ClientHello;

                ContentType contentType = (ContentType)type;
                byte[]      buffer      = this.ReadRecordBuffer(type, record);
                if (buffer == null)
                {
                    // record incomplete (at the moment)
                    internalResult.SetComplete((byte[])null);
                    return;
                }

                // Decrypt message contents if needed
                if (contentType == ContentType.Alert && buffer.Length == 2)
                {
                }
                else if ((this.Context.Read != null) && (this.Context.Read.Cipher != null))
                {
                    buffer = this.decryptRecordFragment(contentType, buffer);
                    DebugHelper.WriteLine("Decrypted record data", buffer);
                }

                // Process record
                switch (contentType)
                {
                case ContentType.Alert:
                    this.ProcessAlert((AlertLevel)buffer [0], (AlertDescription)buffer [1]);
                    if (record.CanSeek)
                    {
                        // don't reprocess that memory block
                        record.SetLength(0);
                    }
                    buffer = null;
                    break;

                case ContentType.ChangeCipherSpec:
                    this.ProcessChangeCipherSpec();
                    break;

                case ContentType.ApplicationData:
                    break;

                case ContentType.Handshake:
                    TlsStream message = new TlsStream(buffer);
                    while (!message.EOF)
                    {
                        this.ProcessHandshakeMessage(message);
                    }
                    break;

                case (ContentType)0x80:
                    this.context.HandshakeMessages.Write(buffer);
                    break;

                default:
                    throw new TlsException(
                              AlertDescription.UnexpectedMessage,
                              "Unknown record received from server.");
                }

                internalResult.SetComplete(buffer);
            }
            catch (Exception ex)
            {
                internalResult.SetComplete(ex);
            }
        }
Пример #47
0
		public byte[] ReceiveRecord(Stream record)
		{
			if (this.context.ReceivedConnectionEnd)
			{
				throw new TlsException(
					AlertDescription.InternalError,
					"The session is finished and it's no longer valid.");
			}

			record_processing.Reset ();
			byte[] recordTypeBuffer = new byte[1];

			int bytesRead = record.Read(recordTypeBuffer, 0, recordTypeBuffer.Length);

			//We're at the end of the stream. Time to bail.
			if (bytesRead == 0)
			{
				return null;
			}

			// Try to read the Record Content Type
			int type = recordTypeBuffer[0];

			// Set last handshake message received to None
			this.context.LastHandshakeMsg = HandshakeType.ClientHello;

			ContentType	contentType	= (ContentType)type;
			byte[] buffer = this.ReadRecordBuffer(type, record);
			if (buffer == null)
			{
				// record incomplete (at the moment)
				return null;
			}

			// Decrypt message contents if needed
			if (contentType == ContentType.Alert && buffer.Length == 2)
			{
			}
			else if ((this.Context.Read != null) && (this.Context.Read.Cipher != null))
			{
				buffer = this.decryptRecordFragment (contentType, buffer);
				DebugHelper.WriteLine ("Decrypted record data", buffer);
			}

			// Process record
			switch (contentType)
			{
			case ContentType.Alert:
				this.ProcessAlert((AlertLevel)buffer [0], (AlertDescription)buffer [1]);
				if (record.CanSeek) 
				{
					// don't reprocess that memory block
					record.SetLength (0); 
				}
				buffer = null;
				break;

			case ContentType.ChangeCipherSpec:
				this.ProcessChangeCipherSpec();
				break;

			case ContentType.ApplicationData:
				break;

			case ContentType.Handshake:
				TlsStream message = new TlsStream (buffer);
				while (!message.EOF)
				{
					this.ProcessHandshakeMessage(message);
				}
				break;

			case (ContentType)0x80:
				this.context.HandshakeMessages.Write (buffer);
				break;

			default:
				throw new TlsException(
					AlertDescription.UnexpectedMessage,
					"Unknown record received from server.");
			}

			record_processing.Set ();
			return buffer;
		}
Пример #48
0
		private byte[] prf(byte[] secret, string label, byte[] random)
		{
			HashAlgorithm md5 = MD5.Create();
			HashAlgorithm sha = SHA1.Create();

			// Compute SHA hash
			TlsStream block = new TlsStream();
			block.Write(Encoding.ASCII.GetBytes(label));
			block.Write(secret);
			block.Write(random);
						
			byte[] shaHash = sha.ComputeHash(block.ToArray(), 0, (int)block.Length);

			block.Reset();

			// Compute MD5 hash
			block.Write(secret);
			block.Write(shaHash);

			byte[] result = md5.ComputeHash(block.ToArray(), 0, (int)block.Length);

			// Free resources
			block.Reset();

			return result;
		}
		public byte[] EncodeRecord(
			ContentType	contentType, 
			byte[]		recordData,
			int			offset,
			int			count)
		{
			if (this.context.ConnectionEnd)
			{
				throw new TlsException(
					AlertDescription.InternalError,
					"The session is finished and it's no longer valid.");
			}

			TlsStream record = new TlsStream();

			int	position = offset;

			while (position < ( offset + count ))
			{
				short	fragmentLength = 0;
				byte[]	fragment;

				if ((count + offset - position) > Context.MAX_FRAGMENT_SIZE)
				{
					fragmentLength = Context.MAX_FRAGMENT_SIZE;
				}
				else
				{
					fragmentLength = (short)(count + offset - position);
				}

				// Fill the fragment data
				fragment = new byte[fragmentLength];
				Buffer.BlockCopy(recordData, position, fragment, 0, fragmentLength);

				if ((this.Context.Write != null) && (this.Context.Write.Cipher != null))
				{
					// Encrypt fragment
					fragment = this.encryptRecordFragment (contentType, fragment);
				}

				// Write tls message
				record.Write((byte)contentType);
				record.Write(this.context.Protocol);
				record.Write((short)fragment.Length);
				record.Write(fragment);

				DebugHelper.WriteLine("Record data", fragment);

				// Update buffer position
				position += fragmentLength;
			}

			return record.ToArray();
		}
Пример #50
0
		public Context(SecurityProtocolType securityProtocolType)
		{
			this.SecurityProtocol	= securityProtocolType;
			this.compressionMethod	= SecurityCompressionType.None;
			this.serverSettings		= new TlsServerSettings();
			this.clientSettings		= new TlsClientSettings();
			this.handshakeMessages	= new TlsStream();
			this.sessionId			= null;
			this.handshakeState		= HandshakeState.None;
			this.random				= RandomNumberGenerator.Create();
		}
		private void ProcessCipherSpecV2Buffer (SecurityProtocolType protocol, byte[] buffer)
		{
			TlsStream codes = new TlsStream(buffer);

			string prefix = (protocol == SecurityProtocolType.Ssl3) ? "SSL_" : "TLS_";

			while (codes.Position < codes.Length)
			{
				byte check = codes.ReadByte();

				if (check == 0)
				{
					// SSL/TLS cipher spec
					short code = codes.ReadInt16();	
					int index = this.Context.SupportedCiphers.IndexOf(code);
					if (index != -1)
					{
						this.Context.Negotiating.Cipher = this.Context.SupportedCiphers[index];
						break;
					}
				}
				else
				{
					byte[] tmp = new byte[2];
					codes.Read(tmp, 0, tmp.Length);

					int tmpCode = ((check & 0xff) << 16) | ((tmp[0] & 0xff) << 8) | (tmp[1] & 0xff);
					CipherSuite cipher = this.MapV2CipherCode(prefix, tmpCode);

					if (cipher != null)
					{
						this.Context.Negotiating.Cipher = cipher;
						break;
					}
				}
			}

			if (this.Context.Negotiating == null)
			{
				throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security");
			}
		}
Пример #52
0
		public virtual void Clear()
		{
			this.compressionMethod	= SecurityCompressionType.None;
			this.serverSettings		= new TlsServerSettings();
			this.clientSettings		= new TlsClientSettings();
			this.handshakeMessages	= new TlsStream();
			this.sessionId			= null;
			this.handshakeState		= HandshakeState.None;

			this.ClearKeyInfo();
		}