Skip to content

v0.67.0 — A name you hold is a way to sign in

Choose a tag to compare

@ralyodio ralyodio released this 27 Aug 19:06

One new command, and it turns something the pit already publishes into a way to sign in.

moshcode name link — a name you hold is a credential

sudo moshcode name link chovy.hacker

The registry already publishes, per name, the SHA-256 of the SubjectPublicKeyInfo that name's certificate has to present. That exists so a client can verify TLS for a name no CA will ever vouch for. But read it the other way round and it is a name-to-key binding nobody else can forge — which is exactly the shape of a credential. Sign something with the pinned key and you have proved you hold the name.

So: name link fetches a challenge from an app, signs the nonce with the key at /etc/ssl/moshpit/<name>.key, and prints a proof bundle. The private key never leaves the machine; the certificate travels with the signature so the far side can recover the key and check it against what the registry publishes.

--app points it at anything that speaks the two endpoints, and defaults to qrypt.chat, which is the first thing to consume it — there, a name replaces a phone number as the identity behind a post-quantum encrypted account. --json hands the bundle to a script instead of a person.

The key is root-owned, which is why the example says sudo. Running without it reports that, rather than an errno.

What it deliberately does not do

It does not generate the app's encryption key, and the reason is worth stating because it looks like an omission.

The pinned key is P-256 and it signs. A messenger's key is ML-KEM-1024 and it encrypts — and a KEM key cannot sign at all. They are two keys with two jobs, one attesting the other. The private half of the second belongs on the device the person actually reads messages on, not in a CLI on whatever box happens to hold the name. So this emits the proof and stops; the app supplies a key it generated itself and never showed anyone.

The bundle is single-use and short-lived. The challenge it answers is burned on redemption, so a copy of it is worth nothing once spent.

One detail that is a real trap rather than a preference: the signature is DER. A P-1363 signature is the same numbers in an encoding the verifier rejects, and that failure is indistinguishable from presenting the wrong key entirely — so the test asserts the signature verifies under the far side's own check rather than merely that one was produced.

The repo now holds QryptChat

apps/qryptchat-web joined apps/pwa in this repo, with its history intact. Nothing about the CLI moved: bin/, src/, plugins/ and install.sh are where they were, this package publishes exactly the files it published before, and no in-flight branch has to be rebased.

One repo, though, is not one dependency tree. Neither app is a workspace member and each installs itself — pnpm-workspace.yaml says why for both. The practical rule is to run pnpm install in the directory you are working in.

The root test runner is now pinned to its own test directories. node --test with no arguments walks the whole tree, which was fine while there was one test framework in here and stops being fine the moment there are two.