Comments (9)
We might change the w.derive_key(purpose, length) -> key
API method to work with an event instead of delivering the raw master key out to the API layer (and leaving the derivation up to them). So we'd add an APIEvent::DeriveKey(purpose, length)
inbound, which would get routed to the Key machine, and if we were in the S4 "know key" state, then fire an APIAction::GotDerivedKey(purpose, length, key)
event, which would be caught by do_api
and translated into an API action enum. Or we could add a third entry point (derive_key
, next to do_api
and do_io
), which would send in the APIEvent but then expect/assert that the only event coming back out was the GotDerivedKey
, and then it could return the result directly instead of as an event (so the impl WormholeCore
would have a pub fn derive_key(&self, purpose: &str, length: u8) -> Result<Vec<u8>, WormholeError>
). This third entry point would return an Err if the key was not yet available (the API says that derive_key
can't be called until after get_verifier
fires, I think).
Also, we should probably prohibit calling derive_key
until the key has been verified too. Currently the Key machine doesn't know about verified/not-verified (it's the Receive machine that notices the first correctly-decrypted message and moves to the "verified" state, and announces the verifier). Maybe we should move that out of Receive and into Key, so Receive would send "got_message" (possibly without a body) to Key, and Key would add another state named "Verified". We could also move responsibility to distributing the "scared" event to Key, as well as got_verifier
(and probably happy
too). So Receive would only ever send out got_message
(to Key and Boss), and something like scared
or decryption failed
or something to Key. Key would send got_key
(which should probably be renamed got_unverified_key
) to Receive and Boss (although why does Boss need it again? revisit that), and would take over sending got_verifier
, got_verified_key
, happy
, and scared
.
from magic-wormhole.rs.
Oh, one problem that showed up so far: the python version submits the entire wormhole code as the "password" into SPAKE2 (so 4-purple-sausages
), but the rust version is only submitting the secret words (purple-sausages
). This needs to change to match the python version. I got the split wrong when I roughed this out.. I'll have to go back to the python version to see what prompted me to do it that way, but adding some print()
s to the python version shows the difference.
from magic-wormhole.rs.
In the S00->S10 transition, it'd be nice to build the PAKE object early, since this can be somewhat CPU intensive, and some day we can push it off to a separate thread, and let the computation run in parallel with waiting for a message from the peer. (on a normal machine, this won't make much of a difference since the SPAKE2 startup call only takes about 320us. But if we're cross-compiled to WASM or running on a raspberry pi or something, it might be nice to parallelize).
from magic-wormhole.rs.
Fixing the truncated SPAKE2 input (basically just delete code.rs line 59) appears to make the shared PAKE key match on both sides. I'm still getting the key-confirmation failure, so now I'm thinking that we're deriving the VERSION key incorrectly (maybe using HKDF differently, maybe using a mismatching "purpose" string).
from magic-wormhole.rs.
With PR #30, derive_phase_key seem to match the python version for fixed inputs. Now, the real culprit seem to be the encrypt_data
. In the python version, the secretbox.encrypt()
returns a bytestring with nonce bytes appended with ciphertext. It looks like the sodiumoxide's seal
function does not do that, it just returns the ciphertext. Trying to figure out what we can do about it.
from magic-wormhole.rs.
Updated PR #30 with a possible fix for encrypt_data
. If I extract the nonce from python version, feed it instead of utils.random()
in the python version, it matches the output.
from magic-wormhole.rs.
We go much further now. Python client does not crash, still displaying "Waiting for the sender" and rust client has its event queue empty, I think.
got message {"server_tx": 1523971715.748189, "type": "ack", "id": null}
msg is "{\"server_tx\": 1523971715.748189, \"type\": \"ack\", \"id\": null}"
got message {"body": "e7a7ebd019e317b7c16d3a4e82bbd6f5f3a5ae649dacfbe0dd4c324faff79242968e4eb257c5b7231f86a986dd5ca49d72f83afff54c33f12cc5faf6", "server_rx": 1523971715.748163, "id": null, "phase": "version", "server_tx": 1523971715.749112, "type": "message", "side": "side1"}
msg is "{\"body\": \"e7a7ebd019e317b7c16d3a4e82bbd6f5f3a5ae649dacfbe0dd4c324faff79242968e4eb257c5b7231f86a986dd5ca49d72f83afff54c33f12cc5faf6\", \"server_rx\": 1523971715.748163, \"id\": null, \"phase\": \"version\", \"server_tx\": 1523971715.749112, \"type\": \"message\", \"side\": \"side1\"}"
event: Mailbox(RxMessage("side1", "version", [101, 55, 97, 55, 101, 98, 100, 48, 49, 57, 101, 51, 49, 55, 98, 55, 99, 49, 54, 100, 51, 97, 52, 101, 56, 50, 98, 98, 100, 54, 102, 53, 102, 51, 97, 53, 97, 101, 54, 52, 57, 100, 97, 99, 102, 98, 101, 48, 100, 100, 52, 99, 51, 50, 52, 102, 97, 102, 102, 55, 57, 50, 52, 50, 57, 54, 56, 101, 52, 101, 98, 50, 53, 55, 99, 53, 98, 55, 50, 51, 49, 102, 56, 54, 97, 57, 56, 54, 100, 100, 53, 99, 97, 52, 57, 100, 55, 50, 102, 56, 51, 97, 102, 102, 102, 53, 52, 99, 51, 51, 102, 49, 50, 99, 99, 53, 102, 97, 102, 54]))
mailbox: current state = S2B("7b7au6srqjhzq"), got event = RxMessage("side1", "version", [101, 55, 97, 55, 101, 98, 100, 48, 49, 57, 101, 51, 49, 55, 98, 55, 99, 49, 54, 100, 51, 97, 52, 101, 56, 50, 98, 98, 100, 54, 102, 53, 102, 51, 97, 53, 97, 101, 54, 52, 57, 100, 97, 99, 102, 98, 101, 48, 100, 100, 52, 99, 51, 50, 52, 102, 97, 102, 102, 55, 57, 50, 52, 50, 57, 54, 56, 101, 52, 101, 98, 50, 53, 55, 99, 53, 98, 55, 50, 51, 49, 102, 56, 54, 97, 57, 56, 54, 100, 100, 53, 99, 97, 52, 57, 100, 55, 50, 102, 56, 51, 97, 102, 102, 102, 53, 52, 99, 51, 51, 102, 49, 50, 99, 99, 53, 102, 97, 102, 54])
side does match! Ours
got message {"body": "e5f2531dc649a835df77abc7ca33155158d4f7c1c3b509921255599815a440269d8e4cc068f2b62e025b84abb9882a1ed0ca1af9ab94dbc57ce4163f", "server_rx": 1523971715.768577, "id": "71a8", "phase": "version", "server_tx": 1523971715.769637, "type": "message", "side": "cd80b1f771"}
msg is "{\"body\": \"e5f2531dc649a835df77abc7ca33155158d4f7c1c3b509921255599815a440269d8e4cc068f2b62e025b84abb9882a1ed0ca1af9ab94dbc57ce4163f\", \"server_rx\": 1523971715.768577, \"id\": \"71a8\", \"phase\": \"version\", \"server_tx\": 1523971715.769637, \"type\": \"message\", \"side\": \"cd80b1f771\"}"
event: Mailbox(RxMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102]))
mailbox: current state = S2B("7b7au6srqjhzq"), got event = RxMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102])
side does not match! Theirs
out: Nameplate(Release)
out: Order(GotMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102]))
event: Nameplate(Release)
event: Order(GotMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102]))
order: current state = S1, got event = GotMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102])
out: Receive(GotMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102]))
event: Receive(GotMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102]))
out: Boss(GotMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102]))
event: Boss(GotMessage("cd80b1f771", "version", [101, 53, 102, 50, 53, 51, 49, 100, 99, 54, 52, 57, 97, 56, 51, 53, 100, 102, 55, 55, 97, 98, 99, 55, 99, 97, 51, 51, 49, 53, 53, 49, 53, 56, 100, 52, 102, 55, 99, 49, 99, 51, 98, 53, 48, 57, 57, 50, 49, 50, 53, 53, 53, 57, 57, 56, 49, 53, 97, 52, 52, 48, 50, 54, 57, 100, 56, 101, 52, 99, 99, 48, 54, 56, 102, 50, 98, 54, 50, 101, 48, 50, 53, 98, 56, 52, 97, 98, 98, 57, 56, 56, 50, 97, 49, 101, 100, 48, 99, 97, 49, 97, 102, 57, 97, 98, 57, 52, 100, 98, 99, 53, 55, 99, 101, 52, 49, 54, 51, 102]))
from magic-wormhole.rs.
I found a bug in key.rs which swapped the code and the appid, which (in addition to causing a subtle and serious security failure) would have broken compatibility with the Python client. You might try checking again now that it's fixed.
from magic-wormhole.rs.
This is working well now, although the derive_key
question is still outstanding. I'll move that to a separate ticket.
from magic-wormhole.rs.
Related Issues (20)
- Panic triggered when sending file to Wormhole William HOT 7
- Bad license badge in README.md HOT 1
- Add a man page HOT 1
- Generate shell completion
- Tab completion HOT 5
- Gather transit connection information programmatically HOT 4
- Sender hangs when the file size is a multiple of 4096 HOT 3
- Provide example code in source form HOT 6
- Add 32bit build on Windows HOT 4
- Allow compiling without clipboard support HOT 1
- transfer: receive wormhole close should not throw error when failed HOT 5
- transfer: program not exiting when sending an empty file HOT 15
- Panics when IPv6 is disabled HOT 5
- Cancellation doesn't work in all cases
- Detect broken TCP connection to peer HOT 1
- Port forwarding crashes HOT 4
- AddrNotAvailable error for IPv4 on Windows HOT 1
- RUSTSEC-2022-0048: xml-rs is Unmaintained HOT 1
- Using tcp relay with tcp:hostname syntax will panic
- Feature Request: cli installable using cargo-install HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from magic-wormhole.rs.