public string loadAllHardlines() { conn.Open(); string sqlQuery = "SELECT DistrictId, HardLineId FROM data_hardlines ORDER BY DistrictId ASC "; queryExecuter = conn.CreateCommand(); queryExecuter.CommandText = sqlQuery; dr = queryExecuter.ExecuteReader(); string hexpacket = ""; while (dr.Read()) { string districtHex = StringUtils.bytesToString_NS(NumericalUtils.uint16ToByteArrayShort((UInt16)dr.GetInt16(0))); string hardlineHex = StringUtils.bytesToString_NS(NumericalUtils.uint16ToByteArray((UInt16)dr.GetInt16(1), 1)); hexpacket = hexpacket + districtHex + hardlineHex + "0000"; } conn.Close(); return(hexpacket); }
public byte[] processHandleAuthChallenge_Response(byte[] data, int maxBytes) { int blobSize = (int)data[4]; byte[] encryptedBlob = new byte[blobSize]; byte[] decryptedBlob = new byte[blobSize]; ArrayUtils.copy(data, 6, encryptedBlob, 0, blobSize); // Reset IV to 0 tf.setIV(blankIV); tf.decrypt(encryptedBlob, decryptedBlob); byte[] receivedMD5 = new byte[16]; ArrayUtils.copy(decryptedBlob, 1, receivedMD5, 0, 16); // Security says that must be the same if (!ArrayUtils.equal(receivedMD5, md5edChallenge)) { Output.WriteLine("The Md5 from client and Our Md5 are not same, aborting"); Output.WriteLine("Decrypted (TF) blob:" + StringUtils.bytesToString(decryptedBlob)); Output.WriteLine("Stored MD5ed Challenge:" + StringUtils.bytesToString(md5edChallenge)); throw new AuthException("Md5 challenge differs"); } // We take the pass from the decrypted Blob and subtract 1 byte, the ending "0" int passSize = ((int)decryptedBlob[23]) - 1; byte[] passwordB = new byte[passSize]; ArrayUtils.copy(decryptedBlob, 25, passwordB, 0, passSize); Output.OptWriteLine("-> Password decrypted, size:" + passSize); // Set WorldList password wl.setPassword(StringUtils.bytesToString_NS(md5.digest(passwordB))); if (Store.dbManager.AuthDbHandler.fetchWordList(ref wl)) { // Do calculations magic byte[] hexUserID = NumericalUtils.uint32ToByteArray((UInt32)wl.getUserID(), 1); byte[] nameH = new byte[33]; string name = wl.getUsername(); for (int i = 0; i < name.Length; i++) { nameH[i] = (byte)name[i]; } byte[] padding = new byte[4]; // 4 empty byte ==> [0x00,0x00,0x00,0x00] // +10 mins from now, so 60secs per min byte[] expiredTime = TimeUtils.getUnixTime(60 * 10); byte[] padding2 = new byte[32]; // 32 empty byte ==> [0x00,0x00,0x00,0x00,...] byte[] pubModulusH = wl.getPublicModulus(); byte[] createdTime = NumericalUtils.uint32ToByteArray((UInt32)wl.getTimeCreated(), 1); // Create signed data DynamicArray signedData = new DynamicArray(); signedData.append(new byte[] { 0x01 }); signedData.append(hexUserID); signedData.append(nameH); signedData.append(new byte[] { 0x00, 0x01 }); signedData.append(padding); signedData.append(expiredTime); signedData.append(padding2); signedData.append(new byte[] { 0x00, 0x11 }); signedData.append(pubModulusH); signedData.append(createdTime); byte[] md5FromStructure = md5.digest(signedData.getBytes()); // Do MD5 to the signed data and RSA encrypt the result byte[] signature = rsa.signWithMD5(md5FromStructure); Output.OptWriteLine("-> Signing with RSA"); // Do: privExp = Twofish(privExp) byte[] privExp = wl.getPrivateExponent(); byte[] buffer = new byte[privExp.Length]; // We keep the Key from before this part // Set the challenge we saved before as IV tf.setIV(challenge); tf.encrypt(privExp, buffer); privExp = buffer; byte [] privExpSize = NumericalUtils.uint16ToByteArray((UInt16)privExp.Length, 1); // Calculate offsets int offsetAuthData = 33 + wl.getCharPack().getPackLength() + wl.getWorldPack().getTotalSize(); int offsetEncryptedData = offsetAuthData + signature.Length + signedData.getSize() + 2; int offsetCharData = 33; int offsetServerData = 33 + wl.getCharPack().getPackLength(); int offsetUsernameLast = offsetEncryptedData + 2 + privExp.Length; // Create the auth header DynamicArray authHeader = new DynamicArray(); authHeader.append(new byte[] { 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); authHeader.append(NumericalUtils.uint16ToByteArray((UInt16)offsetAuthData, 1)); authHeader.append(NumericalUtils.uint16ToByteArray((UInt16)offsetEncryptedData, 1)); authHeader.append(new byte[] { 0x1f, 0x00, 0x00, 0x00 }); authHeader.append(NumericalUtils.uint16ToByteArray((UInt16)offsetCharData, 1)); authHeader.append(new byte[] { 0x6E, 0xD1, 0x00, 0x00 }); authHeader.append(NumericalUtils.uint32ToByteArray((UInt32)offsetServerData, 1)); authHeader.append(NumericalUtils.uint32ToByteArray((UInt32)offsetUsernameLast, 1)); byte [] usernameSize = NumericalUtils.uint16ToByteArray((UInt16)(name.Length + 1), 1); // Create the semiResponse (full data, except the total size) DynamicArray semiResponse = new DynamicArray(); semiResponse.append(authHeader.getBytes()); semiResponse.append(wl.getCharPack().getByteContents()); semiResponse.append(wl.getWorldPack().getByteContents()); semiResponse.append(new byte[] { 0x36, 0x01 }); semiResponse.append(signature); semiResponse.append(signedData.getBytes()); semiResponse.append(privExpSize); semiResponse.append(privExp); semiResponse.append(usernameSize); byte [] tempName = new byte[name.Length]; for (int i = 0; i < name.Length; i++) { tempName[i] = (byte)name[i]; } semiResponse.append(tempName); semiResponse.append(new byte[] { 0x00 }); int bigSize = semiResponse.getSize(); bigSize += 0x8000; // Add TCP Len Var byte [] finalSize = NumericalUtils.uint16ToByteArray((UInt16)bigSize, 0); // Create the finalResponse (full data, plus total size) DynamicArray finalResponse = new DynamicArray(); finalResponse.append(finalSize); finalResponse.append(semiResponse.getBytes()); Output.OptWriteLine("Sending world list."); status = -1; return(finalResponse.getBytes()); } byte [] worldListPacket = { 0x00, 0x00 }; status = -1; // trick return(worldListPacket); }