lotharrr
Joined 13 years ago
Joined 13 years ago
Note that the transit relay only sees ciphertext (for bulk data transfers). Even the mailbox server only sees ciphertext or SPAKE key-exchange messages. No server sees plaintext ever.
Both sides connect to the "mailbox relay server" to perform key exchange and setup. That's a host named "relay.magic-wormhole.io".
If either side has a public IP address, the encrypted data is transferred directly (they exchange IP addresses through the encrypted pipe, and attempt to connect to all of them, so this also covers two peers on the same LAN). If neither do, they both connect to a public "transit helper" relay named "transit.magic-wormhole.io" which acts like a TURN server to get the encrypted bytes from one connection to the other. I run both services.
Debian was kind enough to configure their distribution's copy with a distinct hostname for the transit relay helper (the bit that forwards bulk encrypted traffic when both parties are behind NAT). "magic-wormhole-transit.debian.net" is currently a CNAME for "transit.magic-wormhole.io" (which is what the upstream source uses), so all this currently costs them is some DNS maintenance. Both sides exchange transit server hostnames, so they don't need to use the same one, but Debian does this so we could switch Debian-based clients off to a different server if/when my costs of running transit.magic-wormhole.io grow too large.
The "mailbox relay server" for all mutually-communicating clients must be the same. Both upstream and Debian (and most of the other distributions I've seen) use "relay.magic-wormhole.io". The mailbox server helps the clients exchange tiny key-exchange and setup messages, so its costs are trivial.
I think it's a 2-out-of-3 trilemma: end-to-end encryption, short codes/URLs, offline/non-interactive workflow: choose two. Or framed differently, if you require proper encryption, then either the code/URL must be long enough to hold the full key, or you must use an interactive (PAKE) protocol which means both agents must be running at the same time (babysitting).
Your last point is an interesting one: we could build a form of magic-wormhole where the sender's CLI waits, the recipient gets a URL, the URL points to a web page which performs the client side of the protocol. The server wouldn't host the file, just the decryption agent. Basically wormhole receive in a browser. That would match many of your goals.
However I'd be hesitant to do this with magic-wormhole because it opens up a vulnerability we don't currently have: the web server hosting that page could silently swap out the JS with a version that retained a copy of the plaintext, perhaps only when the browser is coming from a specific IP. You can't audit a webserver for consistent+correct behavior the way you could with e.g. the contents of a Debian distribution.
That said, the usability gains of the recipient not needing a CLI tool installed might be worth the tradeoff for some folks.
(I'm the author of magic-wormhole)
Tor is basically a distributed set of proxy servers, so using onion servers (aka Hidden Services) is a viable, albeit somewhat slow, way to manage even the strict NAT boxes.
If you have Tor installed, then `wormhole send --tor` will automatically use an onion service to do exactly that.
We've sketched out some approaches to working in a disconnected environment like that, using local multicast and mDNS/ZeroConf/Bonjour to act as an alternate mailbox server (https://github.com/magic-wormhole/magic-wormhole/issues/48). There's still design work needed, though, and I fear it would degrade the experience for fully-connected nodes (extra timeouts), so it might want to be opt-in with a `--offline` flag on both sides.
The secret can be any string you like, the protocol doesn't care, instead of "4-purple-sausages" it could be "4-65535" or "4-qtx", and have the same resistance to attack. The CLI encodes the secret as two words from the PGP word list, which was designed to be spoken and transcribed accurately even over a noisy voice channel (sort of like the Alpha/Bravo/Charlie/.. "military phonetic alphabet", except it's two alternating lists of 256 words each). In practice that pair of words is much easier to speak and listen and hold in your head for a minute or two than a random number, or the first two letters of each word divorced from the words themselves.
There are some provisions in the protocol (not yet implemented) to allow alternate word lists, so if the sender uses e.g. a French wordlist instead of the default English one, the receiving CLI learns about it early enough so that "wormhole rx" can auto-complete against the correct list. The server/attacker could learn which wordlist is in use, but still faces the same level of entropy about the PAKE secret itself.
https://github.com/magic-wormhole/magic-wormhole/blob/master... has a larger writeup.
The `wormhole send` tool is a good demonstration of what you can do with that API, and a convenient tool in its own right, but wasn't designed to be the end-all-be-all of the file transfer universe, nor to be a building block for other tools layered on top.
The application you describe would be pretty cool (the UI might look more like dropping a file into a Slack DM chat window). But I'd recommend against using automated calls to `wormhole send` to accomplish it: you'd be cutting against the grain, and adding load to the mailbox server that everyone else uses. Instead, build a separate app or daemon, which can use the magic-wormhole API to perform just the introduction step. You'd push the "invite a peer" button on your app, it would display a wormhole code, you speak that to your pal, they push the "accept invitation" button on their app, type in the code, and then the two apps exchange keys/addresses. All subsequent transfers use those established keys, and don't need to use the wormhole code again. You should never need to perform a wormhole dance more than once per peer.
For GPG to add security, you also have to make sure the GPG key is transferred safely, which adds work to the transfer process. Either you're GPG-encrypting to a public key (which you must have copied from the receiving side to the sending side at some point), or you're using a symmetric-key passphrase (which you must generate randomly, to be secure, and then copy it from one side to the other).
I should note that magic-wormhole's encryption scheme is not post-quantum -secure. So if you've managed to get a GPG symmetric key transferred to both sides via PQ-secure pathways (I see that current SSH 9.8 includes "kex: algorithm: [email protected]", where NTRU is PQ-secure), then your extra GPG encryption will indeed provide you with security against a sufficiently-large quantum computer, whereas just magic-wormhole would be vulnerable.
But wormhole has turned out to be more usable in some cases. I've had days where I'm sshed into a bastion host, then sshed from there into a server, then cd'd into a deep directory with lots of spaces and quotes and shell metacharacters in the path, and then found a file that I wanted to copy out. To do that with ssh, I have to first configure ProxyJump to let me reach the internal machine with a single ssh command, and then figure out how to escape the pathname correctly (which somehow never works for me). With `wormhole send` I get to skip all of that, at the cost of having to do it once per file.
You can also import the wormhole library directly and use its API to run whatever protocol you want. That mode uses the same kinds of codes as the file-sending tool, but with a different "application ID" so they aren't competing for the same short code numbers. https://github.com/magic-wormhole/magic-wormhole/blob/master... has details.