protected SslHandshakeStatus ProcessServerHello(HandshakeMessage message)
 {
     if (m_State != HandshakeType.ClientHello && m_State != HandshakeType.HelloRequest)
     {
         throw new SslException(AlertDescription.UnexpectedMessage, "ServerHello message must be preceded by a ClientHello message.");
     }
     UpdateHashes(message, HashUpdate.All);             // input message
     if (message.fragment.Length < 2 || message.fragment[0] != GetVersion().major || message.fragment[1] != GetVersion().minor)
     {
         throw new SslException(AlertDescription.IllegalParameter, "Unknown protocol version of the client.");
     }
     try {
         // extract the time from the client [== 1 uint]
         m_ServerTime = new byte[4];
         Array.Copy(message.fragment, 2, m_ServerTime, 0, 4);
         // extract the random bytes [== 28 bytes]
         m_ServerRandom = new byte[28];
         Array.Copy(message.fragment, 6, m_ServerRandom, 0, 28);
         // extact the session ID [== 0..32 bytes]
         int length = message.fragment[34];
         if (length > 32)
         {
             throw new SslException(AlertDescription.IllegalParameter, "The length of the SessionID cannot be more than 32 bytes.");
         }
         m_SessionID = new byte[length];
         Array.Copy(message.fragment, 35, m_SessionID, 0, length);
         // extract the selected cipher suite
         m_EncryptionScheme = CipherSuites.GetCipherAlgorithmType(message.fragment, 35 + length);
         // extract the selected compression method
         m_CompressionMethod = CompressionAlgorithm.GetCompressionAlgorithmType(message.fragment, 37 + length);
     } catch (Exception e) {
         throw new SslException(e, AlertDescription.InternalError, "The message is invalid.");
     }
     return(new SslHandshakeStatus(SslStatus.MessageIncomplete, null));
 }
        protected SslHandshakeStatus ProcessServerHello(HandshakeMessage message)
        {
            if (m_State != HandshakeType.ClientHello && m_State != HandshakeType.HelloRequest)
            {
                throw new SslException(AlertDescription.UnexpectedMessage, "ServerHello message must be preceded by a ClientHello message.");
            }

            UpdateHashes(message, HashUpdate.All); // input message

            //Violation with tls spec. If remote side uses higher protocol version than your, then we must answer with your highest version
            //if (message.fragment.Length < 2 || message.fragment[0] != GetVersion().major || message.fragment[1] != GetVersion().minor)
            //throw new SslException(AlertDescription.IllegalParameter, "Unknown protocol version of the client.");

            int currentProcessedLen = 2;

            try {
                // extract the time from the client [== 1 uint]
                m_ServerTime = new byte[4];
                Buffer.BlockCopy(message.fragment, currentProcessedLen, m_ServerTime, 0, 4);
                currentProcessedLen += 4;

                // extract the random bytes [== 28 bytes]
                m_ServerRandom = new byte[28];
                Buffer.BlockCopy(message.fragment, currentProcessedLen, m_ServerRandom, 0, 28);
                currentProcessedLen += 28;

                // extact the session ID [== 0..32 bytes]
                int length = message.fragment[currentProcessedLen++];
                if (length > 32)
                {
                    throw new SslException(AlertDescription.IllegalParameter, "The length of the SessionID cannot be more than 32 bytes.");
                }

                m_SessionID = new byte[length];
                Buffer.BlockCopy(message.fragment, currentProcessedLen, m_SessionID, 0, length);
                currentProcessedLen += length;

                // extract the selected cipher suite
                m_EncryptionScheme   = CipherSuites.GetCipherAlgorithmType(message.fragment, currentProcessedLen);
                currentProcessedLen += 2;

                // extract the selected compression method
                m_CompressionMethod = CompressionAlgorithm.GetCompressionAlgorithmType(message.fragment, currentProcessedLen++);
            }
            catch (Exception e)
            {
                throw new SslException(e, AlertDescription.InternalError, "The message is invalid.");
            }

            if (message.fragment.Length == currentProcessedLen)
            {
                return(new SslHandshakeStatus(SslStatus.MessageIncomplete, null));
            }

            this.ProcessExtensions(message.fragment, ref currentProcessedLen, ConnectionEnd.Client);

            return(new SslHandshakeStatus(SslStatus.MessageIncomplete, null));
        }