Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: support ISAAC + RSA for 235 server compatibility #4

Open
Hubcapp opened this issue Aug 25, 2020 · 20 comments
Open

Feature Request: support ISAAC + RSA for 235 server compatibility #4

Hubcapp opened this issue Aug 25, 2020 · 20 comments

Comments

@Hubcapp
Copy link

Hubcapp commented Aug 25, 2020

// TODO toggle ISAAC
/*seedIsaac(seed) {
//this.isaacIncoming = new ISAAC(seed);
//this.isaacOutgoing = new ISAAC(seed);
}*/

Not sure what else is needed here to enable ISAAC.

Also in

async login(u, p, reconnecting) {
if (this.worldFullTimeout > 0) {
this.showLoginScreenStatus('Please wait...', 'Connecting to server');
await sleep(2000);
this.showLoginScreenStatus('Sorry! The server is currently full.', 'Please try again later');
return;
}
try {
this.username = u;
u = Utility.formatAuthString(u, 20);
this.password = p;
p = Utility.formatAuthString(p, 20);
if (u.trim().length === 0) {
this.showLoginScreenStatus('You must enter both a username', 'and a password - Please try again');
return;
}
if (reconnecting) {
this.drawTextBox('Connection lost! Please wait...', 'Attempting to re-establish');
} else {
this.showLoginScreenStatus('Please wait...', 'Connecting to server');
}
this.packetStream = new PacketStream(await this.createSocket(this.server, this.port), this);
this.packetStream.maxReadTries = GameConnection.maxReadTries;
let l = Utility.usernameToHash(u);
this.packetStream.newPacket(clientOpcodes.SESSION);
this.packetStream.putByte(l.shiftRight(16).and(31).toInt());
this.packetStream.flushPacket();
let sessId = await this.packetStream.getLong();
this.sessionID = sessId;
if (sessId.equals(0)) {
this.showLoginScreenStatus('Login server offline.', 'Please try again in a few mins');
return;
}
console.log('Verb: Session id: ' + sessId);
let ai = new Int32Array(4);
ai[0] = (Math.random() * 99999999) | 0;
ai[1] = (Math.random() * 99999999) | 0;
ai[2] = sessId.shiftRight(32).toInt();
ai[3] = sessId.toInt();
this.packetStream.newPacket(clientOpcodes.LOGIN);
if (reconnecting) {
this.packetStream.putByte(1);
} else {
this.packetStream.putByte(0);
}
this.packetStream.putShort(GameConnection.clientVersion);
this.packetStream.putByte(0); // limit30
this.packetStream.putByte(10);
this.packetStream.putInt(ai[0]);
this.packetStream.putInt(ai[1]);
this.packetStream.putInt(ai[2]);
this.packetStream.putInt(ai[3]);
this.packetStream.putInt(0); // uuid
this.packetStream.putString(u);
this.packetStream.putString(p);
this.packetStream.flushPacket();
//this.packetStream.seedIsaac(ai);
let resp = await this.packetStream.readStream();
console.log('login response:' + resp);
if (resp === 25) {
this.moderatorLevel = 1;
this.autoLoginTimeout = 0;
this.resetGame();
return;
}
if (resp === 0) {
this.moderatorLevel = 0;
this.autoLoginTimeout = 0;
this.resetGame();
return;
}
if (resp === 1) {
this.autoLoginTimeout = 0;
, the login packet isn't encapsulated in RSA, so it won't work for a 235 server. Might be correct for a 204 server, haven't looked into that.

@misterhat
Copy link
Member

misterhat commented Aug 26, 2020

Yeah I explicitly disabled those to make it easier to test my server. JS has native BigInt support now so the RSA can be identical the the regular 204, and the ISAAC class just needs to be ported over or I can just use an ISAAC module instead.

To support 235, some of the chat encoding, friends list, and login packet structures would need to be modified slightly, as well as some of the opcodes. I think a branch of this repository with 235 support would make sense.

@spkaeros
Copy link

spkaeros commented Aug 28, 2020

My fork contains an RSA implementation in both JS and one in Rust. The JS one maybe got removed in master; might have to look to commit history to locate it.

I have ISAAC code in my local copy, however I have stalled dev work lately as 2020 really smacked me in the face recently. Maybe I can put some patches together for you in a little while.

EDIT: A note on my Rust implementation, some form of memory bug might occur where the block of Wasm memory shared with JS apparently contains bad data. I am not sure if it is fixed in that revision or not. In any event, it usually worked fine even when it had this issue.

@Hubcapp
Copy link
Author

Hubcapp commented Aug 28, 2020

Found this note in your fork & didn't look too much further; seems like you went for an updated approach with "room in the future for maybe non-TLS client support".

                // I deprecated the security of the traditional Jagex protocol (rsa+isaac) in favor of traditional TLS mechanisms
                // which are inherently more secure and also we gain the support for it through built-in standardized libraries automatically
                // Even though we no longer need to, I still encrypt the login block for the reason that one may wish to provide non-TLS
                // client support and this will protect the user login credentials in this case.

I've been updating Open RSC & now am able to log into it with RSC+. So in the future, there will actually be a running fully-featured server that supports the RSC235 protocol. Could possibly support 204 client protocol too, I understand it's not that different (haven't looked very closely at 204 client dev personally), but it would be neat if that was not necessary to support 204 & there were a javascript client that supported RSC235.

@spkaeros
Copy link

spkaeros commented Aug 28, 2020

No, the TLS crypto is all automagically taken care of transparently, in the websocket code. The RSA being used in my client is plain jane identical to Jagex. I even made a program in Go to generate exponents and mods.

204 vs 235 is a thing i know a thing or two about. They are incredibly similar, can basically count differences on 2 hands. Biggest hurdle is going to be chat charset encoding. Can discuss further on discord if you like.

Edit: js code here https://github.com/spkaeros/rsc-client/blob/master/src/gamelib/rsa.js
I dont see rust version, chance i never committed it. Be at PC soon and will commit latest probably

@misterhat
Copy link
Member

misterhat commented Aug 28, 2020

JS supports BigInt natively now, so the big-int module isn't required: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#BigInt_type

@spkaeros
Copy link

Indeed. Explored that option brother, found its API sincerely lacking. The from/toArray calls were my hickup to be specific, had wrote a workaround using a conversion function I hand wrote but ran into some form of issue and reverted to the library.

@Jameskmonger
Copy link

Hey @Hubcapp hope you don't mind me getting involved here

I am the author of this https://www.npmjs.com/package/isaac-crypto

It's tested, written in TypeScript (if that's your thing) and is used by a few RS2 projects.

I'd love to help get it set up here if you think it would be useful!

Let me know if you have any questions about it

@Hubcapp
Copy link
Author

Hubcapp commented Oct 5, 2020

Well, I think you @'d the wrong person. I have a lot of projects I'm already working on without getting directly involved in javascript client dev. I'm hoping @spkaeros or @misterhat will get around to it.

Thanks for your input though, it does look like a useful library.

P.S. RSC235 support is now part of the Open RSC code base, and the feature goes live tomorrow.

@misterhat
Copy link
Member

misterhat commented Oct 5, 2020

Yeah @Jameskmonger the ISAAC library looks useful, great work. Makes sense to implement it in rsc-server and rsc-client at some point.

@spkaeros
Copy link

spkaeros commented Oct 6, 2020

Implementation underway here, will keep you posted, hopefully just a few days just looking for time to write the code.

@spkaeros
Copy link

spkaeros commented Feb 16, 2021

Sorry forgot all about this I have redone the networking code in what I view as an improvement, with 235 compliance. Will post soon as am at pc

@Hubcapp
Copy link
Author

Hubcapp commented Feb 17, 2021

Definitely something we're still interested in...!

@spkaeros
Copy link

Definitely something we're still interested in...!

So making a cogent PR here will be a task of its own as our code bases have changed too dramatically just to diff&push. That said I'm working on getting it to you.

@spkaeros
Copy link

spkaeros commented Feb 25, 2021

Am I to assume your preference is to use your network API with my crypto code Frankensteined onto it?

Cos i been perfecting my networking API and truly suhgest its use. Ill do a push to my webclient master shortly as an update for yall

@spkaeros
Copy link

Am I to assume your preference is to use your network API with my crypto code Frankensteined onto it?

Cos i been perfecting my networking API and truly suhgest its use. Ill do a push to my webclient master shortly as an update for yall

Alsi pretty sure frankensteIm patchery is how ORSC gets born. no disrespect intended but seriously isnt it

@Hubcapp
Copy link
Author

Hubcapp commented Feb 26, 2021

Any way you can do it without modifying too much of the OpenRSC source is fine. Ideally it would be RSC235 over websocket instead of TCP.

@spkaeros
Copy link

spkaeros commented Feb 26, 2021

Any way you can do it without modifying too much of the OpenRSC source is fine. Ideally it would be RSC235 over websocket instead of TCP.

Obviously over ws; unless looking to make a connection after forcing a browser plugin installation on our end users. If you'd seen my private rsc-client any time last few months, focus has been on standardizng many things, and modernizing things I deemed to outdated. The reason I bring that up, I have implemented a src/packets.js which has a func for each client opcode packets builder. Keep this would mean I can give you my patch like now, but I gutted src/packet.js and src/network-stream.js they are NOTHING like Jagex's and packet is even unused, the Packet class when needed is found embedded in the desired stream I/O class as I felt there were far too great number of files total. Also I use webpack 5 now, custom bigint rsa where I took modpow from the big-num? package, src/lib/isaac.js is just basically an encapsulated isaac module and we now import xtea out of npm. So some reasons I bring this things up, a direct port is going to be a bitch. It'd be far easier to just follow my login procedures along and copy-paste their functionality, so this is my path forward but my recomendation for structuring is to do similar in the near future to my changeset. My input handling is also totally redone, incl. src/net/lib/{socket,file-download-stream} and both mouse/kb. I changed if I had to estimate 75-90% of the codebase. Lemme know thoughts yes???

Intriguingly, back to using my Android phone for a main driver here for dev work, will be ordering highest end pine device to replace soon enough alrdy got thte NVME SSD for it.

@Jameskmonger
Copy link

Hey 👋 I don't know if this is also useful to you @spkaeros, but I also wrote an almost feature-complete implementation of the buffer logic here

https://github.com/Jameskmonger/rs-buffer

It's in TypeScript, and unit tested - not sure how similar this is between 317 and rsc but if it's useful I'm also happy to help get this set up 👍 If there's anything you think is missing which would make it easier to use please let me know

@Jameskmonger
Copy link

It handles the different endianness as well as the different transformations 😄

@Hubcapp
Copy link
Author

Hubcapp commented Feb 28, 2021

As long as it is to RSC235 spec & client behaviour isn't apparently different to users, I don't mind any drastic rewrites you mention. Those are the only goals that matter to me though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants