Open ChristopherA opened 4 years ago
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.
@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.
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:
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.
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
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?
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:
"<salt>|<priv-key>"
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