public HandshakeMessage[] ProcessHandshakeRecord(ProtocolVersion version, Record record) { List <HandshakeMessage> ret = new List <HandshakeMessage>(); // Write record to input stream and attempt to parse a handshake message _inputStream.Write(record.Fragment, 0, record.Fragment.Length); while (_inputStream.Length - _inputtedBytes >= 4) { byte[] inputBuffer = _inputStream.GetBuffer(); int dataLength = (inputBuffer[_inputtedBytes + 1] << 16) | (inputBuffer[_inputtedBytes + 2] << 8) | inputBuffer[_inputtedBytes + 3]; // Check that if we have enough data to read message now if (4 + dataLength > _inputStream.Length - _inputtedBytes) { break; } byte[] msgData = new byte[4 + dataLength]; long writePosition = _inputStream.Position; // Read message data from inputStream _inputStream.Position = _inputtedBytes; _inputStream.Read(msgData, 0, msgData.Length); _inputStream.Position = writePosition; _inputtedBytes += msgData.Length; // Add resulting handshake message to the results ret.Add(HandshakeMessage.GetInstance(version, msgData)); } if (_inputtedBytes == _inputStream.Length) { // Reset stream to save memory _inputStream.Position = 0; _inputStream.SetLength(0); _inputtedBytes = 0; } return(ret.ToArray()); }
public bool ReadPacket(Stream stream) { byte[] header = new byte[5]; int readBytes = 0; while (readBytes < header.Length) { readBytes += stream.Read(header, readBytes, header.Length - readBytes); } Record record = new Record(header); readBytes = 0; while (readBytes < record.Fragment.Length) { readBytes += stream.Read(record.Fragment, readBytes, record.Fragment.Length - readBytes); } _recordHandler.ProcessInputRecord(record); if (record.Type == 22) { HandshakeMessage hs = HandshakeMessage.GetInstance(VERSION, record.Fragment); if (hs == null) { Console.WriteLine("Skipped handling packet"); return(true); } Console.WriteLine("adding bytes to hash " + record.Fragment.Length); _handshakeStream.Write(record.Fragment, 0, record.Fragment.Length); if (hs.Type == HandshakeMessageType.ServerHello) { HandshakeServerHello sh = (HandshakeServerHello)hs; _serverRandom = sh.Random.GetBytes(); if (sh.ServerVersion != VERSION) { throw new Exception("Version doesn't match"); } } else if (hs.Type == HandshakeMessageType.Certificate) { Console.WriteLine("Found certificate"); HandshakeCertificate cert = (HandshakeCertificate)hs; _rsaPublicKey = null; foreach (X509Certificate c in cert.CertificateList) { Console.WriteLine(c.ToString(true)); if (_rsaPublicKey == null) { X509Certificate c2 = new X509Certificate(c); _rsaPublicKey = new CertificatePublicKey(c2); } } } else if (hs.Type == HandshakeMessageType.ServerHelloDone) { SendClientKey(stream); byte[] seed = new byte[64]; Array.Copy(_clientRandom, 0, seed, 0, 32); Array.Copy(_serverRandom, 0, seed, 32, 32); PrintBytes("hash seed", seed); _masterSecret = _cipherSuite.KeyExchangeAlgorithm.GetMasterSecret(_cipherSuite.PseudoRandomFunction, seed); PrintBytes("master secret", _masterSecret); seed = new byte[64]; Array.Copy(_serverRandom, 0, seed, 0, 32); Array.Copy(_clientRandom, 0, seed, 32, 32); ConnectionState connectionState = new ConnectionState(_clientRandom, _serverRandom, _masterSecret); _recordHandler.SetCipherSuite(_cipherSuite, connectionState); SendFinished(stream); } else if (hs.Type == HandshakeMessageType.Finished) { Console.WriteLine("Got Finished message!!!"); SendHttpGet(stream); } } else if (record.Type == 20) { Console.WriteLine("Got change cipher spec from server"); _recordHandler.ChangeRemoteState(); } else if (record.Type == 21) { // This is an alert if (record.Fragment.Length >= 2 && record.Fragment[1] == 0) { // Close notify Console.WriteLine("Close notify received"); return(false); } } else if (record.Type == 23) { Console.WriteLine("Got data: " + Encoding.UTF8.GetString(record.Fragment)); } return(true); }