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

Requirements for next version of QuickConnect #66

Open
ChristopherA opened this issue May 17, 2020 · 6 comments
Open

Requirements for next version of QuickConnect #66

ChristopherA opened this issue May 17, 2020 · 6 comments

Comments

@ChristopherA
Copy link
Contributor

QuickConnect is currently offered by BitcoinStandup (both Mac and Linux), BTCPayServer, Nodl, MyNode, RaspiBlitz full node tools and hardware, and is used currently by FullyNoded, FullyNoded2, and a couple of other experimental apps to allow secure connection via Tor v3 from a remote to your own personal full node. 

However, we know that QuickConnect needs another major iteration, and welcome contributions to requirements and/or proposals for the next version.

We invite you to share your thoughts here.

-- Christopher Allen

@Fonta1n3
Copy link
Contributor

I can't think of anything it needs, at least certainly not for it's current stated purpose. FWIW it's built with the ability to add as many optional parameters as you would like.

@Fonta1n3
Copy link
Contributor

Fonta1n3 commented Sep 7, 2020

@ChristopherA I have put more thought into this, it is becoming apparent that many services will be offered (are offered) all of which require their own QR. Umbrel is using a scheme for deriving their onion hostnames deterministically which is a clever way of doing it, then you do not need to transmit the uri's at all, just add words to your light client for remote connection.

In the meantime I think it will also be useful to simply send an array of encrypted uri's to the light client, it can just do what it needs to do with each one based on the prefixes. The user ideally specifying a password which is used to encrypt/decrypt on both ends (considering if this is leaked an attacker will get everything).

I am more leaning towards doing this as a .quickconnect file as QR's seem to unnecessarily over complicate it.

@05nelsonm
Copy link

05nelsonm commented Dec 30, 2020

So I would like to re-spec how I'm passing connection information from node to client. As I've yet to release my application and corresponding libraries, doing so now in order to standardize things would I think be best for all.

Currently, I've build a cli for user's node (bash scripts) to:

  • setup hidden service
  • generate v3 client auth key pair and install in client auth dir of specified HS
  • build string with connection info
  • encrypt string with user defined password & hash iterations using OpenSSL
  • (work in progress) generate QR codes to scan in import into client

Raw URL prior to encryption:

// Actual is a single line string value. **returns inserted for readability purposes only**
toxicityconnect://v1
?<onion-address.onion>:<connection-port>
?v3_priv_key=<v3-client-auth-private-key>
?service_type=<service-type>
?username=<u-name>
?password=<p-word>
?tls_cert=<tls-cert>

Encrypted URL to be passed

toxicityconnect://v1?<encrypted-data>

Encryption used server side

openssl aes-256-cbc -e -a -p -salt -pbkdf2 -iter <user defined hash iterations, 20k+ required> -k <user defined password>

Have built a Kotlin implementation that is forward/backward compat with OpenSSL (b/c openssl is "unique" in how it does things) to decrypt/encrypt client side.

The UI/UX surrounding user input of a 52 character, base32 encoded v3 auth priv key is very challenging and most will simply opt out of using V3 authentication key pairs all together.

I debated it for quite a while and felt it better to include it and simply encrypt the entire string value (also... because credentials should absolutely never be passed in the clear, no exceptions, ever, ever, ever). This also allows for users to pre-load Toxicity with shareable connections for services (such as Esplora, CoinOS, etc) to share with other Toxicity users (friends/family). If a device is compromised (lost, confiscated by The State), simply remove the public key from the HS to invalidate the connection.

The data is brought into the Application's Process via clipboard or Scanning a QR code (still working on this) where it can be decrypted "safely". This is a necessity, as I (my application) do not own the Camera Process, nor the Clipboard's. Only once it's been brought into the memory allocated to my application's Process can there be a meaningful level of assurance that decryption of the highly sensitive connection information won't leak data via heap dump analysis or scanning from other potentially malicious applications that have access to the other processes.

Any suggestions/collaboration would be much appreciated, thanks.

@Fonta1n3
Copy link
Contributor

Just after a quick read I would strongly disagree with passing the v3 auth private key along with the onion hostname, the whole point is these two are separate entities. The private key should be produced "out of band" by the client (not the server) as per the v3 spec: https://github.com/torproject/torspec/blob/12271f0e6db00dee9600425b2de063e02f19c1ee/rend-spec-v3.txt#L645

@05nelsonm
Copy link

Just after a quick read I would strongly disagree with passing the v3 auth private key along with the onion hostname, the whole point is these two are separate entities. The private key should be produced "out of band" by the client (not the server) as per the v3 spec: https://github.com/torproject/torspec/blob/12271f0e6db00dee9600425b2de063e02f19c1ee/rend-spec-v3.txt#L645

Yes, but from the next line it elaborates on generation of private key server side.

An easier but less secure way of doing this exchange would be to have the
hidden service generate the keypairs and pass the corresponding private keys
to its clients.

The context surrounding the suggested security implications of either method is one of the client not knowing or controlling the HS; in our use case, we own/operate the node. V3 authorization in our case is being used simply to inhibit anyone who may get the onion address from connecting, as well as allowing operators the ability to quickly invalidate keys that are compromised.

I'd definitely agree that if I was connecting to a rando HS, I'd generate keys client side and provide the pub key for authorization.

The UX surrounding this, too, is hugely inhibiting such that users will simply opt out of using keys to lock down their connection which defeats the purpose. I think Nicolas Dorier posted about this UX challeng on Twitter actually, and said he simply didn't use v3 authorization b/c of it.

Thoughts on my thoughts?

@05nelsonm
Copy link

05nelsonm commented Dec 31, 2020

What if a key is generated server side, and a hash of it is passed in the URL. Then the user types in the key and it can be verified by comparing the hashes?

User flow:

  • v3 priv key is salted and hashed "<salt>|<priv-key>"
  • user enters password
  • url is built with hash of priv key and encrypted
  • user scans QR code with client
  • decrypts data
  • enters the salt + v3 priv key
  • compare hashes to validate

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

3 participants