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();
        }
Beispiel #2
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();
        }