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();
        }
Пример #2
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();
        }
Пример #3
0
 public static bool SetContextInCache(Context context)
 {
     lock (ClientSessionCache.locker)
     {
         ClientSessionInfo clientSessionInfo = ClientSessionCache.FromContext(context, false);
         if (clientSessionInfo == null)
         {
             return(false);
         }
         clientSessionInfo.GetContext(context);
         clientSessionInfo.KeepAlive();
         return(true);
     }
 }
 internal override void OnNegotiateHandshakeCallback(IAsyncResult asyncResult)
 {
     this.protocol.EndSendRecord(asyncResult);
     while (this.context.LastHandshakeMsg != HandshakeType.ServerHelloDone)
     {
         this.SafeReceiveRecord(this.innerStream);
         if (this.context.AbbreviatedHandshake && this.context.LastHandshakeMsg == HandshakeType.ServerHello)
         {
             break;
         }
     }
     if (this.context.AbbreviatedHandshake)
     {
         ClientSessionCache.SetContextFromCache(this.context);
         this.context.Negotiating.Cipher.ComputeKeys();
         this.context.Negotiating.Cipher.InitializeCipher();
         this.protocol.SendChangeCipherSpec();
         while (this.context.HandshakeState != HandshakeState.Finished)
         {
             this.SafeReceiveRecord(this.innerStream);
         }
         this.protocol.SendRecord(HandshakeType.Finished);
     }
     else
     {
         bool flag = this.context.ServerSettings.CertificateRequest;
         if (this.context.SecurityProtocol == SecurityProtocolType.Ssl3)
         {
             flag = (this.context.ClientSettings.Certificates != null && this.context.ClientSettings.Certificates.Count > 0);
         }
         if (flag)
         {
             this.protocol.SendRecord(HandshakeType.Certificate);
         }
         this.protocol.SendRecord(HandshakeType.ClientKeyExchange);
         this.context.Negotiating.Cipher.InitializeCipher();
         if (flag && this.context.ClientSettings.ClientCertificate != null)
         {
             this.protocol.SendRecord(HandshakeType.CertificateVerify);
         }
         this.protocol.SendChangeCipherSpec();
         this.protocol.SendRecord(HandshakeType.Finished);
         while (this.context.HandshakeState != HandshakeState.Finished)
         {
             this.SafeReceiveRecord(this.innerStream);
         }
     }
     this.context.HandshakeMessages.Reset();
     this.context.ClearKeyInfo();
 }
Пример #5
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();
        }
Пример #6
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();
        }
        public static bool SetContextInCache(Context context)
        {
            object obj = ClientSessionCache.locker;
            bool   result;

            lock (obj)
            {
                ClientSessionInfo clientSessionInfo = ClientSessionCache.FromContext(context, false);
                if (clientSessionInfo == null)
                {
                    result = false;
                }
                else
                {
                    clientSessionInfo.GetContext(context);
                    clientSessionInfo.KeepAlive();
                    result = true;
                }
            }
            return(result);
        }
Пример #8
0
        private void NegotiateAsyncWorker(IAsyncResult result)
        {
            NegotiateAsyncResult negotiate = result.AsyncState as NegotiateAsyncResult;

            try
            {
                switch (negotiate.State)
                {
                case NegotiateState.SentClientHello:
                    this.protocol.EndSendRecord(result);

                    // we are now ready to ready the receive the hello response.
                    negotiate.State = NegotiateState.ReceiveClientHelloResponse;

                    // Start reading the client hello response
                    this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate);
                    break;

                case NegotiateState.ReceiveClientHelloResponse:
                    this.SafeEndReceiveRecord(result, true);

                    if (this.context.LastHandshakeMsg != HandshakeType.ServerHelloDone &&
                        (!this.context.AbbreviatedHandshake || this.context.LastHandshakeMsg != HandshakeType.ServerHello))
                    {
                        // Read next record (skip empty, e.g. warnings alerts)
                        this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate);
                        break;
                    }

                    // special case for abbreviated handshake where no ServerHelloDone is sent from the server
                    if (this.context.AbbreviatedHandshake)
                    {
                        ClientSessionCache.SetContextFromCache(this.context);
                        this.context.Negotiating.Cipher.ComputeKeys();
                        this.context.Negotiating.Cipher.InitializeCipher();

                        negotiate.State = NegotiateState.SentCipherSpec;

                        // Send Change Cipher Spec message with the current cipher
                        // or as plain text if this is the initial negotiation
                        this.protocol.BeginSendChangeCipherSpec(NegotiateAsyncWorker, negotiate);
                    }
                    else
                    {
                        // Send client certificate if requested
                        // even if the server ask for it it _may_ still be optional
                        bool clientCertificate = this.context.ServerSettings.CertificateRequest;

                        using (var memstream = new MemoryStream())
                        {
                            // NOTE: sadly SSL3 and TLS1 differs in how they handle this and
                            // the current design doesn't allow a very cute way to handle
                            // SSL3 alert warning for NoCertificate (41).
                            if (this.context.SecurityProtocol == SecurityProtocolType.Ssl3)
                            {
                                clientCertificate = ((this.context.ClientSettings.Certificates != null) &&
                                                     (this.context.ClientSettings.Certificates.Count > 0));
                                // this works well with OpenSSL (but only for SSL3)
                            }

                            byte[] record = null;

                            if (clientCertificate)
                            {
                                record = this.protocol.EncodeHandshakeRecord(HandshakeType.Certificate);
                                memstream.Write(record, 0, record.Length);
                            }

                            // Send Client Key Exchange
                            record = this.protocol.EncodeHandshakeRecord(HandshakeType.ClientKeyExchange);
                            memstream.Write(record, 0, record.Length);

                            // Now initialize session cipher with the generated keys
                            this.context.Negotiating.Cipher.InitializeCipher();

                            // Send certificate verify if requested (optional)
                            if (clientCertificate && (this.context.ClientSettings.ClientCertificate != null))
                            {
                                record = this.protocol.EncodeHandshakeRecord(HandshakeType.CertificateVerify);
                                memstream.Write(record, 0, record.Length);
                            }

                            // send the chnage cipher spec.
                            this.protocol.SendChangeCipherSpec(memstream);

                            // Send Finished message
                            record = this.protocol.EncodeHandshakeRecord(HandshakeType.Finished);
                            memstream.Write(record, 0, record.Length);

                            negotiate.State = NegotiateState.SentKeyExchange;

                            // send all the records.
                            this.innerStream.BeginWrite(memstream.GetBuffer(), 0, (int)memstream.Length, NegotiateAsyncWorker, negotiate);
                        }
                    }
                    break;

                case NegotiateState.SentKeyExchange:
                    this.innerStream.EndWrite(result);

                    negotiate.State = NegotiateState.ReceiveFinishResponse;

                    this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate);

                    break;

                case NegotiateState.ReceiveFinishResponse:
                    this.SafeEndReceiveRecord(result);

                    // Read record until server finished is received
                    if (this.context.HandshakeState != HandshakeState.Finished)
                    {
                        // If all goes well this will process messages:
                        //      Change Cipher Spec
                        //		Server finished
                        this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate);
                    }
                    else
                    {
                        // Reset Handshake messages information
                        this.context.HandshakeMessages.Reset();

                        // Clear Key Info
                        this.context.ClearKeyInfo();

                        negotiate.SetComplete();
                    }
                    break;


                case NegotiateState.SentCipherSpec:
                    this.protocol.EndSendChangeCipherSpec(result);

                    negotiate.State = NegotiateState.ReceiveCipherSpecResponse;

                    // Start reading the cipher spec response
                    this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate);
                    break;

                case NegotiateState.ReceiveCipherSpecResponse:
                    this.SafeEndReceiveRecord(result, true);

                    if (this.context.HandshakeState != HandshakeState.Finished)
                    {
                        this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate);
                    }
                    else
                    {
                        negotiate.State = NegotiateState.SentFinished;
                        this.protocol.BeginSendRecord(HandshakeType.Finished, NegotiateAsyncWorker, negotiate);
                    }
                    break;

                case NegotiateState.SentFinished:
                    this.protocol.EndSendRecord(result);

                    // Reset Handshake messages information
                    this.context.HandshakeMessages.Reset();

                    // Clear Key Info
                    this.context.ClearKeyInfo();

                    negotiate.SetComplete();

                    break;
                }
            }
            catch (TlsException ex)
            {
                try {
                    Exception e = ex;
                    this.protocol.SendAlert(ref e);
                } catch {
                }
                negotiate.SetComplete(new IOException("The authentication or decryption has failed.", ex));
            }
            catch (Exception ex)
            {
                try {
                    this.protocol.SendAlert(AlertDescription.InternalError);
                } catch {
                }
                negotiate.SetComplete(new IOException("The authentication or decryption has failed.", ex));
            }
        }
Пример #9
0
        internal override void OnNegotiateHandshakeCallback(IAsyncResult asyncResult)
        {
            this.protocol.EndSendRecord(asyncResult);

            // Read server response
            while (this.context.LastHandshakeMsg != HandshakeType.ServerHelloDone)
            {
                // Read next record
                SafeReceiveRecord(this.innerStream);

                // special case for abbreviated handshake where no ServerHelloDone is sent from the server
                if (this.context.AbbreviatedHandshake && (this.context.LastHandshakeMsg == HandshakeType.ServerHello))
                {
                    break;
                }
            }

            // the handshake is much easier if we can reuse a previous session settings
            if (this.context.AbbreviatedHandshake)
            {
                ClientSessionCache.SetContextFromCache(this.context);
                this.context.Negotiating.Cipher.ComputeKeys();
                this.context.Negotiating.Cipher.InitializeCipher();

                // Send Cipher Spec protocol
                this.protocol.SendChangeCipherSpec();

                // Read record until server finished is received
                while (this.context.HandshakeState != HandshakeState.Finished)
                {
                    // If all goes well this will process messages:
                    //      Change Cipher Spec
                    //		Server finished
                    SafeReceiveRecord(this.innerStream);
                }

                // Send Finished message
                this.protocol.SendRecord(HandshakeType.Finished);
            }
            else
            {
                // Send client certificate if requested
                // even if the server ask for it it _may_ still be optional
                bool clientCertificate = this.context.ServerSettings.CertificateRequest;

                // NOTE: sadly SSL3 and TLS1 differs in how they handle this and
                // the current design doesn't allow a very cute way to handle
                // SSL3 alert warning for NoCertificate (41).
                if (this.context.SecurityProtocol == SecurityProtocolType.Ssl3)
                {
                    clientCertificate = ((this.context.ClientSettings.Certificates != null) &&
                                         (this.context.ClientSettings.Certificates.Count > 0));
                    // this works well with OpenSSL (but only for SSL3)
                }

                if (clientCertificate)
                {
                    this.protocol.SendRecord(HandshakeType.Certificate);
                }

                // Send Client Key Exchange
                this.protocol.SendRecord(HandshakeType.ClientKeyExchange);

                // Now initialize session cipher with the generated keys
                this.context.Negotiating.Cipher.InitializeCipher();

                // Send certificate verify if requested (optional)
                if (clientCertificate && (this.context.ClientSettings.ClientCertificate != null))
                {
                    this.protocol.SendRecord(HandshakeType.CertificateVerify);
                }

                // Send Cipher Spec protocol
                this.protocol.SendChangeCipherSpec();

                // Send Finished message
                this.protocol.SendRecord(HandshakeType.Finished);

                // Read record until server finished is received
                while (this.context.HandshakeState != HandshakeState.Finished)
                {
                    // If all goes well this will process messages:
                    //      Change Cipher Spec
                    //		Server finished
                    SafeReceiveRecord(this.innerStream);
                }
            }

            // Reset Handshake messages information
            this.context.HandshakeMessages.Reset();

            // Clear Key Info
            this.context.ClearKeyInfo();
        }
Пример #10
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();
        }
Пример #11
0
        public override void ComputeKeys()
        {
            TlsStream tlsStream = new TlsStream();
            char      c         = 'A';
            int       num       = 1;

            while (tlsStream.Length < base.KeyBlockSize)
            {
                string text = string.Empty;
                for (int i = 0; i < num; i++)
                {
                    text += c.ToString();
                }
                byte[] array = prf(base.Context.MasterSecret, text.ToString(), base.Context.RandomSC);
                int    count = (tlsStream.Length + array.Length <= base.KeyBlockSize) ? array.Length : (base.KeyBlockSize - (int)tlsStream.Length);
                tlsStream.Write(array, 0, count);
                c = (char)(c + 1);
                num++;
            }
            TlsStream tlsStream2 = new TlsStream(tlsStream.ToArray());

            base.Context.Negotiating.ClientWriteMAC = tlsStream2.ReadBytes(base.HashSize);
            base.Context.Negotiating.ServerWriteMAC = tlsStream2.ReadBytes(base.HashSize);
            base.Context.ClientWriteKey             = tlsStream2.ReadBytes(base.KeyMaterialSize);
            base.Context.ServerWriteKey             = tlsStream2.ReadBytes(base.KeyMaterialSize);
            if (!base.IsExportable)
            {
                if (base.IvSize != 0)
                {
                    base.Context.ClientWriteIV = tlsStream2.ReadBytes(base.IvSize);
                    base.Context.ServerWriteIV = tlsStream2.ReadBytes(base.IvSize);
                }
                else
                {
                    base.Context.ClientWriteIV = CipherSuite.EmptyArray;
                    base.Context.ServerWriteIV = CipherSuite.EmptyArray;
                }
            }
            else
            {
                HashAlgorithm hashAlgorithm = MD5.Create();
                int           num2          = hashAlgorithm.HashSize >> 3;
                byte[]        outputBuffer  = new byte[num2];
                hashAlgorithm.TransformBlock(base.Context.ClientWriteKey, 0, base.Context.ClientWriteKey.Length, outputBuffer, 0);
                hashAlgorithm.TransformFinalBlock(base.Context.RandomCS, 0, base.Context.RandomCS.Length);
                byte[] array2 = new byte[base.ExpandedKeyMaterialSize];
                Buffer.BlockCopy(hashAlgorithm.Hash, 0, array2, 0, base.ExpandedKeyMaterialSize);
                hashAlgorithm.Initialize();
                hashAlgorithm.TransformBlock(base.Context.ServerWriteKey, 0, base.Context.ServerWriteKey.Length, outputBuffer, 0);
                hashAlgorithm.TransformFinalBlock(base.Context.RandomSC, 0, base.Context.RandomSC.Length);
                byte[] array3 = new byte[base.ExpandedKeyMaterialSize];
                Buffer.BlockCopy(hashAlgorithm.Hash, 0, array3, 0, base.ExpandedKeyMaterialSize);
                base.Context.ClientWriteKey = array2;
                base.Context.ServerWriteKey = array3;
                if (base.IvSize > 0)
                {
                    hashAlgorithm.Initialize();
                    outputBuffer = hashAlgorithm.ComputeHash(base.Context.RandomCS, 0, base.Context.RandomCS.Length);
                    base.Context.ClientWriteIV = new byte[base.IvSize];
                    Buffer.BlockCopy(outputBuffer, 0, base.Context.ClientWriteIV, 0, base.IvSize);
                    hashAlgorithm.Initialize();
                    outputBuffer = hashAlgorithm.ComputeHash(base.Context.RandomSC, 0, base.Context.RandomSC.Length);
                    base.Context.ServerWriteIV = new byte[base.IvSize];
                    Buffer.BlockCopy(outputBuffer, 0, base.Context.ServerWriteIV, 0, base.IvSize);
                }
                else
                {
                    base.Context.ClientWriteIV = CipherSuite.EmptyArray;
                    base.Context.ServerWriteIV = CipherSuite.EmptyArray;
                }
            }
            ClientSessionCache.SetContextInCache(base.Context);
            tlsStream2.Reset();
            tlsStream.Reset();
        }
Пример #12
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();
        }