Skip to main content

Module tls

Module tls 

Source
Expand description

A certificate authority that can only ever vouch for one suffix.

The https mode needs a certificate the browser accepts for <alias>.<suffix>, and nobody will issue one: the suffix is not a real TLD and there is no way to prove control of it. So the daemon makes its own authority, and the whole question is how much damage that authority could do if its key leaked.

A stock local CA — what mkcert installs — could impersonate any site on the internet. The key sits in a file on a laptop, and trusting it means trusting that file more than the web PKI. This one carries nameConstraints with a single permitted subtree, the configured suffix, so a leaked key can mint certificates for *.ssh-browser and for nothing else. RFC 5280 §4.2.1.10 requires that extension to be marked critical, which is what stops a conforming verifier from quietly ignoring it.

Two more limits, for the same reason:

  • basicConstraints carries pathLenConstraint: 0, so this authority cannot sign another authority. Without it a leaked key could mint an intermediate; the name constraint would still hold, but the blast radius would grow to whatever that intermediate signed.
  • keyUsage is keyCertSign and crlSign only, so the key cannot serve TLS itself.

Every one of those three is read back out of the encoded certificate by x509-parser, which is not the code that wrote it. Asserting against rcgen’s own view would only say that the builder remembered what it was told; a browser reads bytes, so the tests read bytes.

And the constraint is enforced, measured rather than assumed. A name constraint is worth exactly what the verifier reading it chooses to do, and “required by the RFC” and “honoured by the browser on your desk” are different claims. With a CA of this shape in the current user’s root store, two leaves signed by it, and a browser that was not told to ignore certificate errors:

openssl s_clientChromium
a name under the suffixVerify return code: 0 (ok)loaded, isSecureContext: true
evil.example47 (permitted subtree violation)refused, net::ERR_CERT_INVALID

And what the mode is for is measured too. Through the daemon, against a real SSH host, an https alias origin reports isSecureContext: true with navigator.serviceWorker, crypto.subtle and caches all present — the three things an http alias origin does not have, and the reason this exists.

The same run is what ruled out a wildcard certificate: see Authority::leaf_for.

Firefox and Safari are unmeasured. Firefox keeps its own store and does not read the system one, which trust_instructions says; whether it honours the constraint is the same question again, and not one to answer by assuming.

The daemon never installs this. Putting a root into a trust store changes how the whole machine treats the internet, is not undone by uninstalling a Rust binary, and is not a decision a background process should make. ssh-browser trust prints the command for the platform and stops; running it is the reader’s, with the command in front of them.

Structs§

Authority
The authority’s certificate and the key that signs with it.
Leaf
A serving certificate and its key, both as PEM.
Limits
What the encoded certificate says about how far it may reach.

Enums§

Found
Whether the authority was already there, which decides how loudly to say what to do next.
Store
Which trust store the instructions are for.

Constants§

AUTHORITY_NAME
The stem of every authority’s name.

Functions§

authority_dir
Where the authority lives between runs.
certificate_path
Where the certificate to be trusted goes. Named so ssh-browser trust can print it without creating an authority.
common_name
The exact common name of the authority for suffix.
instructions_for
Printed, never executed. The three differ in more than spelling: the Windows one needs no elevation and writes to this account only, the macOS one prompts for a password and writes to the login keychain, and on Linux the location depends on the distribution while Firefox keeps its own store regardless. Guessing wrong while running as somebody’s shell is not a thing to do quietly.
limits_of
Read the limits out of a PEM certificate.
load_or_create
Load the authority for suffix, or make one and write it down.
load_or_create_reporting
The same, saying which of the two happened.
permits_only
Is this certificate an authority that can vouch for suffix and nothing else?
spki_pin
Base64 of the SHA-256 of a certificate’s SubjectPublicKeyInfo.
trust_instructions
What to run to trust this authority, for the platform this is running on.