Exemple #1
0
        /// <summary>
        /// Start network encryption. Automatically called by Login() if the server requests encryption.
        /// </summary>
        /// <returns>True if encryption was successful</returns>
        private bool StartEncryption(string uuid, string sessionID, byte[] token, string serverIDhash, byte[] serverKey)
        {
            System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey);
            byte[] secretKey = CryptoHandler.GenerateAESPrivateKey();

            if (Settings.DebugMessages)
            {
                ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated.");
            }

            if (serverIDhash != "-")
            {
                Console.WriteLine("Checking Session...");
                if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey)))
                {
                    handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session.");
                    return(false);
                }
            }

            //Encrypt the data
            byte[] key_enc   = dataTypes.GetArray(RSAService.Encrypt(secretKey, false));
            byte[] token_enc = dataTypes.GetArray(RSAService.Encrypt(token, false));

            //Encryption Response packet
            SendPacket(0x01, dataTypes.ConcatBytes(key_enc, token_enc));

            //Start client-side encryption
            socketWrapper.SwitchToEncrypted(secretKey);

            //Process the next packet
            int         packetID   = -1;
            List <byte> packetData = new List <byte>();

            while (true)
            {
                ReadNextPacket(ref packetID, packetData);
                if (packetID == 0x00) //Login rejected
                {
                    handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(dataTypes.ReadNextString(packetData)));
                    return(false);
                }
                else if (packetID == 0x02) //Login successful
                {
                    login_phase = false;

                    if (!pForge.CompleteForgeHandshake())
                    {
                        return(false);
                    }

                    StartUpdating();
                    return(true);
                }
                else
                {
                    HandlePacket(packetID, packetData);
                }
            }
        }
Exemple #2
0
        internal void HandleS01EncryptionRequest(S01EncryptionRequest s01EncryptionRequest)
        {
            waitingForEncryption = true;
            Console.WriteLine("Server is in online mode!");
            RSACryptoServiceProvider rsaProvider = CryptoHandler.DecodeRSAPublicKey(s01EncryptionRequest.serverKey);

            byte[] secretKey = CryptoHandler.GenerateAESPrivateKey();

            Console.WriteLine("Keys generated");
            if (s01EncryptionRequest.serverId != "-")
            {
                Console.WriteLine("Logging in to Mojang");
                if (!Yggdrasil.SessionCheck(manager.loginParams.UUID, manager.loginParams.SessionId, CryptoHandler.getServerHash(s01EncryptionRequest.serverId, s01EncryptionRequest.serverKey, secretKey)))
                {
                    Console.WriteLine("Mojang authentication failed");
                    return;
                }
                else
                {
                    Console.WriteLine("Mojang authentication succesful");
                }
            }

            manager.SendPacket(new C01EncryptionResponse(rsaProvider.Encrypt(secretKey, false), rsaProvider.Encrypt(s01EncryptionRequest.token, false)));

            manager.aesStream = CryptoHandler.getAesStream(manager.tcpClient.GetStream(), secretKey);
            manager.encrypted = true;
        }
        private bool StartEncryption(string uuid, string username, string sessionID, byte[] token, string serverIDhash, byte[] serverKey)
        {
            System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey);
            byte[] secretKey = CryptoHandler.GenerateAESPrivateKey();

            if (Settings.DebugMessages)
            {
                ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated.");
            }

            if (serverIDhash != "-")
            {
                Console.WriteLine("Checking Session...");
                if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey)))
                {
                    handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session.");
                    return(false);
                }
            }

            //Encrypt the data
            byte[] key_enc   = RSAService.Encrypt(secretKey, false);
            byte[] token_enc = RSAService.Encrypt(token, false);
            byte[] keylen    = BitConverter.GetBytes((short)key_enc.Length);
            byte[] tokenlen  = BitConverter.GetBytes((short)token_enc.Length);

            Array.Reverse(keylen);
            Array.Reverse(tokenlen);

            //Building the packet
            byte[] data = new byte[5 + (short)key_enc.Length + (short)token_enc.Length];
            data[0] = 0xFC;
            keylen.CopyTo(data, 1);
            key_enc.CopyTo(data, 3);
            tokenlen.CopyTo(data, 3 + (short)key_enc.Length);
            token_enc.CopyTo(data, 5 + (short)key_enc.Length);

            //Send it back
            Send(data);

            //Getting the next packet
            byte[] pid = new byte[1];
            Receive(pid, 0, 1, SocketFlags.None);
            if (pid[0] == 0xFC)
            {
                readData(4);
                s         = CryptoHandler.getAesStream(c.GetStream(), secretKey);
                encrypted = true;
                return(true);
            }
            else
            {
                ConsoleIO.WriteLineFormatted("§8Invalid response to StartEncryption packet");
                return(false);
            }
        }
Exemple #4
0
        /// <summary>
        /// Start network encryption. Automatically called by Login() if the server requests encryption.
        /// </summary>
        /// <returns>True if encryption was successful</returns>

        private bool StartEncryption(string uuid, string sessionID, byte[] token, string serverIDhash, byte[] serverKey)
        {
            System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey);
            byte[] secretKey = CryptoHandler.GenerateAESPrivateKey();

            ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated.");

            if (serverIDhash != "-")
            {
                Console.WriteLine("Checking Session...");
                if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey)))
                {
                    handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session.");
                    return(false);
                }
            }

            //Encrypt the data
            byte[] key_enc   = RSAService.Encrypt(secretKey, false);
            byte[] token_enc = RSAService.Encrypt(token, false);
            byte[] key_len   = getVarInt(key_enc.Length);
            byte[] token_len = getVarInt(token_enc.Length);

            //Encryption Response packet
            SendPacket(0x01, concatBytes(key_len, key_enc, token_len, token_enc));

            //Start client-side encryption
            s         = CryptoHandler.getAesStream(c.GetStream(), secretKey, this);
            encrypted = true;

            //Process the next packet
            int packetID = -1;

            byte[] packetData = new byte[] { };
            while (true)
            {
                readNextPacket(ref packetID, ref packetData);
                if (packetID == 0x00) //Login rejected
                {
                    handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(readNextString(ref packetData)));
                    return(false);
                }
                else if (packetID == 0x02) //Login successful
                {
                    login_phase = false;
                    StartUpdating();
                    return(true);
                }
                else
                {
                    handlePacket(packetID, packetData);
                }
            }
        }
        /// <summary>
        /// Start network encryption. Automatically called by Login() if the server requests encryption.
        /// </summary>
        /// <returns>True if encryption was successful</returns>

        private bool StartEncryption(string uuid, string sessionID, byte[] token, string serverIDhash, byte[] serverKey)
        {
            System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey);
            byte[] secretKey = CryptoHandler.GenerateAESPrivateKey();

            ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated.");

            if (serverIDhash != "-")
            {
                Console.WriteLine("Checking Session...");
                if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey)))
                {
                    handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session.");
                    return(false);
                }
            }

            //Encrypt the data
            byte[] key_enc   = RSAService.Encrypt(secretKey, false);
            byte[] token_enc = RSAService.Encrypt(token, false);
            byte[] key_len   = BitConverter.GetBytes((short)key_enc.Length); Array.Reverse(key_len);
            byte[] token_len = BitConverter.GetBytes((short)token_enc.Length); Array.Reverse(token_len);

            //Encryption Response packet
            byte[] packet_id                  = getVarInt(0x01);
            byte[] encryption_response        = concatBytes(packet_id, key_len, key_enc, token_len, token_enc);
            byte[] encryption_response_tosend = concatBytes(getVarInt(encryption_response.Length), encryption_response);
            Send(encryption_response_tosend);

            //Start client-side encryption
            s         = CryptoHandler.getAesStream(c.GetStream(), secretKey, this);
            encrypted = true;

            //Read and skip the next packet
            int  received_packet_size = readNextVarInt();
            int  received_packet_id   = readNextVarInt();
            bool encryption_success   = (received_packet_id == 0x02);

            if (received_packet_id == 0)
            {
                handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(readNextString()));
            }
            else
            {
                readData(received_packet_size - getVarInt(received_packet_id).Length);
            }
            if (encryption_success)
            {
                StartUpdating();
            }
            return(encryption_success);
        }
        public bool SwitchToEncrypted(string serverID, byte[] Serverkey, byte[] token)
        {
            if (ServerData.OnlineMode)
            {
                var    crypto    = CryptoHandler.DecodeRSAPublicKey(Serverkey);
                byte[] secretKey = CryptoHandler.GenerateAESPrivateKey();
                byte[] key_enc   = crypto.Encrypt(secretKey, false);
                byte[] token_enc = crypto.Encrypt(token, false);
                //Console.WriteLine(key_enc.Length + " " + token_enc.Length);

                SendPacket(0x01, concatBytes(getArray(key_enc), getArray(token_enc)));

                this.s    = CryptoHandler.getAesStream(c.GetStream(), secretKey);
                encrypted = true;

                int         packetID   = -1;
                List <byte> packetData = new List <byte>();
                while (true)
                {
                    readNextPacket(ref packetID, packetData);
                    if (packetID == 0x00)
                    {
                        handler.OnConnectionLost(Conn.DisconnectReason.LoginRejected, readNextString(packetData));
                        return(false);
                    }
                    else if (packetID == 0x02)//Logined
                    {
                        Debug.Log("Login Success");
                        login_phase = false;
                        handler.OnLogin(packetData);
                        StartUpdating();
                        return(true);
                    }
                    else
                    {
                        if (packetID == 0x03 && login_phase)
                        {
                            if (protocolversion >= MCVersion.MC18Version)
                            {
                                compression_treshold = readNextVarInt(packetData);
                            }
                        }
                        handler.receivePacket(packetID, packetData);
                    }
                }
            }
            else
            {
                handler.OnConnectionLost(Conn.DisconnectReason.LoginRejected, ServerData.MsgEncryptReject);
            }
            return(false);
        }
    /// <summary>
    /// Gets the next packet from the server
    /// </summary>
    /// <returns></returns>
    public PacketData ReadNextPacket()
    {
        int packetId;

        byte[] payload;

        lock (_streamReadLock)
        {
            int         length = VarInt.ReadNext(ReadBytes);
            List <byte> buffer = new List <byte>();

            // check if data is compressed
            if (_compressionThreshold >= 0)
            {
                int dataLength = VarInt.ReadNext(ReadBytes);
                length -= VarInt.GetBytes(dataLength).Length;                   // remove size of data length from rest of packet length
                if (dataLength != 0)
                {
                    byte[] compressedBuffer = ReadBytes(length);
                    buffer.AddRange(ZlibStream.UncompressBuffer(compressedBuffer));
                }
                else
                {
                    buffer.AddRange(ReadBytes(length));
                }
            }
            else
            {
                buffer.AddRange(ReadBytes(length));
            }

            packetId = VarInt.ReadNext(buffer);
            payload  = buffer.ToArray();
        }

        // handles some stuff during login phase
        if (State == ProtocolState.LOGIN)
        {
            // handle compression packet
            if (packetId == (int)ClientboundIDs.LogIn_SetCompression)
            {
                _compressionThreshold = VarInt.ReadNext(new List <byte>(payload));
                return(ReadNextPacket());
            }

            // handle protocol encryption packet
            if (packetId == (int)ClientboundIDs.LogIn_EncryptionRequest)
            {
                var encRequestPkt = new EncryptionRequestPacket()
                {
                    Payload = payload
                };

                var aesSecret = CryptoHandler.GenerateSharedSecret();
                var authHash  = CryptoHandler.SHAHash(Encoding.ASCII.GetBytes(encRequestPkt.ServerID).Concat(aesSecret, encRequestPkt.PublicKey));

                Debug.Log($"Sending hash to Mojang servers: {authHash}");

                // check session with mojang
                if (!MojangAPI.JoinServer(authHash))
                {
                    throw new UnityException("Invalid session. (Try restarting game or relogging into Minecraft account)");
                }

                // use pub key to encrypt shared secret
                using (var rsaProvider = CryptoHandler.DecodeRSAPublicKey(encRequestPkt.PublicKey))
                {
                    byte[] encSecret = rsaProvider.Encrypt(aesSecret, false);
                    byte[] encToken  = rsaProvider.Encrypt(encRequestPkt.VerifyToken, false);

                    // respond to server with private key
                    var responsePkt = new EncryptionResponsePacket()
                    {
                        SharedSecret = encSecret,
                        VerifyToken  = encToken
                    };
                    WritePacket(responsePkt);


                    // enable aes encryption
                    _aesStream = new AesStream(Client.GetStream(), aesSecret);
                    _encrypted = true;

                    // read the next packet
                    return(ReadNextPacket());
                }
            }
        }

        return(new PacketData
        {
            ID = packetId,
            Payload = payload
        });
    }