internal void ProcessData(BinaryReader data) { // [ErrorCode 1](ErrorCode == 0: [EncryptionMethod 1][EncryptionMagicValue 4] [RemotePublicKey 256]( EncryptionMethod == AUTH: [PasswordSalt 16])) ErrorCode = data.ReadByte(); if (ErrorCode == 0) { EncryptionMethod = (EEncryptionMethod)data.ReadByte(); EncryptedMagicValue = BBProtocol.ReadByteArray(data); if (EncryptedMagicValue.Length != 4) { IsValid = false; return; } RemotePublicKey = BBProtocol.ReadByteArray(data); if (RemotePublicKey.Length != 256) { IsValid = false; return; } if (EncryptionMethod == EEncryptionMethod.DH_PLUS_AUTH) { PasswordSalt = BBProtocol.ReadByteArray(data); if (PasswordSalt.Length != 16) { IsValid = false; return; } } } IsValid = true; }
public BbTcpPacket_StartEncryption(byte byProtolVersion, EEncryptionMethod method, byte[] abyLocalPublicKey, byte[] abyLocalIV, byte[] abyRemoteIV) : base(BBProtocol.OP_STARTENCRYPTION, byProtolVersion) { if (abyLocalPublicKey.Length != 256 || abyLocalIV.Length != 16 || abyRemoteIV.Length != 16) { throw new ArgumentException("Invalid Encryption data for remote client"); } Method = method; LocalPublicKey = abyLocalPublicKey; LocalIV = abyLocalIV; RemoteIV = abyRemoteIV; }
private async Task HandlePacket(BbTcpPacket packet) { if (packet is BbTcpPacket_Hello_Ans && m_bRequestedHello) { m_bRequestedHello = false; BbTcpPacket_Hello_Ans hello_ans = (BbTcpPacket_Hello_Ans)packet; ServerName = hello_ans.Desc; ServerGUID = hello_ans.ServerGUID; ServerMinProtocolVersion = hello_ans.MinSupportedVersion; m_bRequiresPassword = hello_ans.RequiresPassword; UsedProtocolVersion = (byte)Math.Min(hello_ans.MaxSupportedVersion, BBProtocol.CURRENT_PROTOCOL_VERSION); if (UsedProtocolVersion < hello_ans.MinSupportedVersion || UsedProtocolVersion < BBProtocol.MIN_PROTOCOL_VERSION) { ProtocolIncompatible = true; Log.w(TAG, "Server supported protocol versions incompatible - " + ServerName); Disconnect(false, true); } SupportsScreenCapture = hello_ans.SupportsScreenCapture; IsProVersion = hello_ans.IsProVersion; Log.d(TAG, "Received Hello Answer from " + ServerName + " Protocol Version: " + UsedProtocolVersion + " Needs Password: "******"Got Pong"); } else if (packet is BbTcpPacket_EncryptionACK crypt) { await ContinueEncryptionNegotiation(crypt); } else if (packet is BbTcpPacket_Encryption_AuthAns auth) { if (m_abyTestedSharedSecret != null) { if (auth.ErrorCode == 0) { Log.d(TAG, "DH+Auth negotiated encryption key for session is: " + BitConverter.ToString(m_abyTestedSharedSecret)); m_sendStreamCipher.Init(m_abyTestedSharedSecret); m_recvStreamCipher.Init(m_abyTestedSharedSecret); m_bAuthentificated = true; m_abyTestedSharedSecret = null; m_dhKeyExchange = null; m_requestedEncryptionMethod = EEncryptionMethod.NONE; Log.d(TAG, "Password accepted, DH+Auth Encryption negotiation finished, transmissions will now be encrypted with " + m_sendStreamCipher.Algorithm); Attach(); } else { Log.w(TAG, "Challenge failed - Password rejected. Trying again."); m_abyTestedSharedSecret = null; await Authenticate(true); } } else { Log.e(TAG, "Unexpected/Unrequested Encryption_AuthAns packet"); Disconnect(false, false); } } else if (packet is BbTcpPacket_Attach_Ans attach_ans && m_bRequestedAttach) { m_bRequestedAttach = false; if (attach_ans.AttachResult == EAttachResult.ACCEPTED) { Attached = true; WasAttached = true; ConnectedTime.Start(); Connecting = false; ConnectionChanged?.Invoke(this, new ConnectionEventArgs(ConnectionEventArgs.EState.CONNECTED, SessionID)); Log.d(TAG, "Attached to " + ServerName); } else { Log.d(TAG, "Cannot Attach to " + ServerName + " Error: " + attach_ans.AttachResult); Disconnect(false, false); } }