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)); }