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

Have Client<->Server agree cipher rather than hardcoded #43

Closed
benaadams opened this issue Jul 28, 2017 · 20 comments
Closed

Have Client<->Server agree cipher rather than hardcoded #43

benaadams opened this issue Jul 28, 2017 · 20 comments

Comments

@benaadams
Copy link

benaadams commented Jul 28, 2017

As per https (TLS) have the client and server agree what cipher suite to use rather than hardcode it as ChaCha20/Poly1305

This will allow platform encryption libraries to be used (e.g. native Win/macOS, and chosen Linux); which will be updated with the natural flow of OS security patches - rather than having a game lib dependency which relies on the developer to release patched versions. (though could still use libsodium if preferred)

Also allows for new ciphers and old ciphers to be depreciated; or prioritized by OS security updates rather than requiring game updates.

@Drawaes
Copy link

Drawaes commented Jul 28, 2017

It's pretty important to be able to remove ciphers when they have been found to be rubbish. Also AES is a lot faster than chacha if you are talking Intel. ChaCha is only really preferable for non Intel chips

@gafferongames
Copy link
Contributor

gafferongames commented Jul 28, 2017

I'm OK to consider this for a 1.1 version of netcode.io. We should also provide private/public key support, so we don't need shared public keys between matcher and server instances, opening the way for user hosted servers. Anything else you can think of?

@gafferongames
Copy link
Contributor

How about instead of saying client/server agree, we simply say that mulitple cipher options are available, and the web backend decides which one is used. This way, a client when connected to the web backend over HTTPS would negotiate which cipher they want to use, or fall back to a default (perhaps AES). This keeps the protocol between client and server simple, but provides the same benefits you describe.

@gafferongames
Copy link
Contributor

Also, are we talking about the cipher set to use for the connect token, challenge token, packets between client and server, or all of the above?

@Drawaes
Copy link

Drawaes commented Jul 28, 2017

I think the connection token should/will have minimal perf impact. It's the "stream" encryption I would focus on.

@Drawaes
Copy link

Drawaes commented Jul 28, 2017

As for "agree" if you take the SSL/TLS model, it is normally the client spits up a set they can support in order of preference, then it is up to the server to decide what it does, does it honour the clients preference or say, nah I want this one specifically.

@benaadams
Copy link
Author

benaadams commented Jul 28, 2017

This way, a client when connected to the web backend over HTTPS would negotiate which cipher they want to use, or fall back to a default (perhaps AES).

Yep this is what I was thinking; likely it will be the same as what is used for HTTPS, but in most servers what encryption https is using is generally opaque as you don't really care, just that is "being handled"; so some way of communicating it on UDP "connection" start up.

Also the web server may hand off to a different server for the UDP; or have https offload at load balancer, so some negotiation may be needed. Something like https does:

The handshake begins when a client connects to a TLS-enabled server requesting a secure connection and the client presents a list of supported cipher suites (ciphers and hash functions) - in preferred order.

From this list, the server picks a cipher and hash function that it also supports and notifies the client of the decision.

However, as the startup/auth is done encrypted (e.g. under https); have a lot of leeway on key exchange etc, and only need one off session keys?

Though @Drawaes knows more about encryption protocols and their implementations than me 😄

@gafferongames
Copy link
Contributor

gafferongames commented Jul 29, 2017

As for "agree" if you take the SSL/TLS model, it is normally the client spits up a set they can support > in order of preference, then it is up to the server to decide what it does, does it honour the clients
preference or say, nah I want this one specifically.

I know, but we don't have to blindly follow how other protocols work.

I don't think there is any value to doing it that way in this case, and in fact it would make netcode.io worse.

A netcode.io client cannot connect to a server without authenticating with the web backend and getting a connect token, so we can simply negotiate that crypto at that point instead.

@gafferongames
Copy link
Contributor

Closing this because it's pretty clear what to do for netcode 1.1 spec at this point.

@Drawaes
Copy link

Drawaes commented Jul 29, 2017

I wasn't meaning you have to do it at end server time, I was simply saying the concept of the client gives a "list" and then later a "server" (front end auth server or the runtime server) makes the final call. That stops clients from forcing bad decisions.

@gafferongames
Copy link
Contributor

gafferongames commented Jul 29, 2017

Yes, the client provides a list to the web backend upon requesting a connect token. Will add this to 1.1

@z-s-e
Copy link

z-s-e commented Aug 13, 2018

I am kind of new to UDP-based protocols, so this might be an uninformed question, but I was also wondering why encryption and authentication is baked into the protocol, instead of simply wrapping it in DTLS.

I'd think an independent authentication/crypto layer such as DTLS is desirable for being able to update it without having to updating/breaking the base protocol as well as not having to maintain the lower level crypto code yourself (but delegate that to the TLS library).

If DTLS is somehow unfit for these kinds of protocols, maybe you could give some insight to this in one of your upcoming blog posts? And btw, thank you very much for your blog, it is very inspiring and well written.

@gafferongames
Copy link
Contributor

It's to keep it simple.

@z-s-e
Copy link

z-s-e commented Aug 13, 2018

If by "simple" you mean kind of "self-contained" or "understandable down to the upd packet", that is a fair goal to have.

But your protocol itself would certainly be more simple if it didn't have any authentication/crypto stuff in it and just rely on the upper layer to provide that - especially if you plan to add cipher suite negotiation as well which is known to be a possible attack vector (as has been in TLS). Personally I'd rather rely on a standard than something self written there. Though I may just take this all to seriously anyway, it is not a protocol for banking transactions after all ;)

@gafferongames
Copy link
Contributor

gafferongames commented Aug 13, 2018

Yes we wish for netcode.io to be simple to understand, self-contained and secure.

I disagree that using DTLS would make this library simpler. It would make it more complex. Since we have no cipher suite negotiation by design, that attack vector does not exist. Less is more.

We use very secure cryptography primitives from libsodium. No need to rely on DTLS standard for security. If you think chacha poly AEAD IETF primitive in about to be broken soon, I guess we have other problems.

If you wish to use a standard, please go ahead, but that's not what this library is about, and it never will be. We can do better than just throwing our hands up in the air and trusting a standard.

cheers

@z-s-e
Copy link

z-s-e commented Aug 13, 2018

Using state of the art standard cryptographic primitives is not enough though, you can still have security vulnerabilities in the protocol itself - the mentioned TLS negotiation problem was also more in the protocol than the primitives afaiu.

You certainly seem competent enough to be able to get the protocol right in this regard. I was more coming from your blog posts that encourage writing one's own specialized protocol. For someone who isn't a crypto expert (like me), wouldn't you rather recommend using DTLS (assuming netcode.io does not fit the intended purpose) instead of doing this protocol part by hand?

Anyway, I hope I didn't pester you too much. Thanks again

@Drawaes
Copy link

Drawaes commented Aug 13, 2018

I think if you fully control both ends you managed to make a point about security just above. That is by making no negotiation and stripping away uneeded features you actually can make a far more secure protocol. Negotiation of ciphers for instance is a huge attack area in TLS DTLS

@gafferongames
Copy link
Contributor

gafferongames commented Aug 13, 2018 via email

@Drawaes
Copy link

Drawaes commented Aug 13, 2018

Yeah.. I don't know if it came across as so but I was backing your approach ;) it also cuts down on protocol overhead if you remove negotiations.

@gafferongames
Copy link
Contributor

gafferongames commented Aug 13, 2018 via email

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

No branches or pull requests

4 participants