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

Session descriptor signing and verification support #19

Open
expenses opened this issue Apr 28, 2022 · 4 comments
Open

Session descriptor signing and verification support #19

expenses opened this issue Apr 28, 2022 · 4 comments

Comments

@expenses
Copy link

expenses commented Apr 28, 2022

Hi! I just found this project recently and it seems super useful. The symmetric encryption scheme mentioned in https://github.com/dmotz/trystero#encryption looks very nice for preventing MITM attacks when the room password is private. However, I'm looking into building a system with public rooms, so the symmetric encryption is not viable for me. What I'd like is a scheme where each peer generated a public/private keypair and uses that to encrypt the SDPs, like what SaltyRTC does except decentralized (https://saltyrtc.org).

When a new peer B is found, peer A would need to encrypt it's SDP offer with peer B's public key. Peer B would then decrypt the SDP, make an answer and encrypt it with peer A's public key, sending it back. These public keys could either be gossipped or known in advance.

How possible is it for something like this to be implemented? I don't know a lot about how the BitTorrent tracker websocket works. Would it allow sending messages like this?

Edit: I'm re-opening this as support for session descriptor signing. See #19 (comment).

@expenses
Copy link
Author

Sigh My thinking was pretty pidgeon-holed when I wrote this. Trying to prevent a MITM for a public server is unnecessary because it's just that; public! If someone wanted to snoop on conversations they'd just connect normally. There is a benefit to having everyone generation public/private keypairs which is that you can verify their identity by having them sign a nouce, but this can be implemented as a layer on top of this library. There's a small benefit to having asymmetric encryption for private rooms, but it's minor enough that I don't think it's worth adding. I'll close this issue now.

@dmotz
Copy link
Owner

dmotz commented Apr 29, 2022

Yeah the encryption feature in Trystero is for a pretty limited use case. The idea was that a public medium operator (e.g. someone running a torrent tracker) can see the plaintext SDPs and then potentially peer with anybody by sending an answer, so a Trystero-based app can add a symmetric key to prevent that. Symmetric keys of course rely on some shared secret that must be communicated or known by other means, so the canonical use case might be something like a chat app where a password is shared via URL query string. In the end users are still anonymous and there is no verified identity via any of this.

I anticipate Trystero users will build their own asymmetric authentication solutions on top that work post-peering, but I've been considering adding an easy/agnostic way to verify/reject a peer from the room via some predicate function you can pass to the library. In this function you could do something like a challenge signing like you mention. Would this be useful/interesting for your use case?

@expenses
Copy link
Author

So the challenge signing method I mentioned doesn't actually prevent MITM, because the MITM can forward the challenge and response between the two parties and take over from there. However, I have come up with a much better solution, which is to key-sign the session descriptors. I've implemented this in a (WIP) branch here: main...expenses:key-signing.

Essentially, you bundle a public key and a signature along with the session descriptor blob (I'm just going to call them SDPs even if that isn't technically accurate). This slightly increases the size of the data sent to the tracker, but only maybe by 50% because ECDSA keys are quite small. You then verify the SDP with the key, making sure you don't connect to the peer if it isn't valid. Finally you add the key to the Peer object and pass it to onPeerJoin (we could probably do this another way) so that a user of the library can pull out the key and know who they're connected to (See https://github.com/expenses/webxr-pbr/blob/451a8964412c6960b594f2ddc119a0634ee9e260/web/index.html#L67-L94).

This doesn't stop a MITM from removing the signature and re-signing or replacing the SDP, but no matter what, if a SDP is signed by a key you recognize then you know it's really them.

I'll try and tidy up the branch a bit more. Let me know if you're open to merging it!

@expenses
Copy link
Author

expenses commented May 2, 2022

If we figure it it how to recover the public key from the signature (see diafygi/webcrypto-examples#37) then we could further reduce the data that's sent to the tracker.

@expenses expenses changed the title Asymmetric encryption support Session descriptor signing and verification support May 2, 2022
@expenses expenses reopened this May 2, 2022
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

2 participants