Skip to content
audiotale.net
Sign in
GuidesExplainer

How TLS certificate trust and revocation work, and how to check your own systems

Roots, intermediates, trust stores and revocation explained step by step, using this week's eMudhra intermediate-certificate compromise as the worked example.

audiotale.net team

· 7 min read

Written by AI from the sources linked below. How we use AI

On this page
  1. In short
  2. The three parts of the system
  3. Why a weak intermediate key is so serious
  4. How a bad certificate is taken back: revocation
  5. A worked example: looking at a chain yourself
  6. Check your own systems, step by step
  7. What to remember
  8. Sources

In short

When your browser, curl or a Python script connects over HTTPS, it accepts a server's certificate only if it can build a chain from that certificate to a root it already trusts. The roots live in a trust store that your browser, operating system, language runtime or container image ships. A flaw in any link of the chain, such as the weak eMudhra intermediate keys found this week, breaks the guarantee for every site, and fixing it means updating the trust store in every place that keeps a copy.

The three parts of the system

A certificate binds a public key to a name (for example a domain) and is signed by an issuer. Anyone who holds the matching private key can prove they are the named server. The certificate says nothing on its own; its value comes from who signed it.

A certification path. RFC 5280, the standard that defines Internet certificate handling, explains that such chains, "called certification paths", are needed because a user is only initialised with a limited number of trusted CA public keys. The path runs from the server's certificate, through zero or more CA certificates, to a CA the user already trusts. At each step the issuer name in one certificate is matched with the subject name of the CA certificate above it, and the signature is checked.

A trust store. This is the list of root certificates a piece of software trusts. Firefox and Chrome maintain their own stores; Windows and Apple platforms keep theirs in the operating system; Linux distributions package Mozilla's list as a ca-certificates package; and many programs bundle another copy. Python's certifi package and Electron apps carry their own, and cryptography maintainer Filippo Valsorda told Ars Technica that some ecosystems, Python among them, commonly ship their own copy of the roots.

In practice the root certificate authority keeps its private key offline and signs a few intermediate certificates. The intermediates issue the certificates that websites actually use. That keeps the valuable root key out of daily use, but it also means an intermediate's private key is powerful: whoever has it can issue a certificate for any domain, and software that trusts the root will accept it.

Why a weak intermediate key is so serious

The eMudhra incident shows the mechanism. According to Ars Technica, eight intermediate certificates had private keys of 3 to 8 bits of entropy, where a normal P-384 key has about 384; the values were 4, 56, 66, 115, 155, 156, 230 and 237. BleepingComputer, citing Mozilla's incident report, says testing 256 numbers was enough to recover each key. With a recovered key, a forged certificate verifies like any other. Our full news report has the timeline and the patch list.

What a forged certificate lets an attacker do is also limited, and it helps to be precise. Ars Technica stresses that exploiting such certificates requires an active attacker who sits between the client and the server, receives the encrypted traffic, decrypts it, re-encrypts it and passes it on. TLS's encryption algorithms are not broken; what fails is the authentication, the guarantee that you are talking to the real server. Cloudflare makes the same distinction: the issue addresses certificate-based authentication, "not a weakness in TLS's encryption algorithms".

How a bad certificate is taken back: revocation

If a certificate or an intermediate must stop being trusted before it expires, the issuer or the browser vendors have to revoke it. This turns out to be the hard part of the system.

  • CRLs. A certificate revocation list, per RFC 5280, is "a time-stamped list identifying revoked certificates that is signed by a CA or CRL issuer", identified by serial number. Mozilla's security engineers note that CRLs grew large and mostly held irrelevant entries, so browsers did not download them.
  • OCSP. The Online Certificate Status Protocol lets a client ask the CA about one certificate. Mozilla reported that over 7% of OCSP checks time out among Beta users, that it adds about 130 ms to a first connection, and that it tells the CA which HTTPS host a user visits. Because a check cannot be made mandatory without breaking sites, a network attacker can simply block it, and the browser carries on.
  • OneCRL and CRLSets. Browser vendors therefore keep their own centrally managed lists for serious incidents. Mozilla's OneCRL is "administratively managed" and handles major security incidents, while Chrome uses CRLSets. Cloudflare's write-up on eMudhra says these quick-revocation mechanisms are the reason browsers could fix the problem with "a flip of a switch", and BleepingComputer reports that Mozilla blocked the certificates through OneCRL without needing a browser update or restart.
  • CRLite. Mozilla describes a design that compresses all Web PKI revocations using cascading Bloom filters, reducing about 300 MB of data to about 1 MB, so that checks happen locally without a network request. The post, from January 2020, described it as in testing in Firefox Nightly; check the current state before relying on it.

The lesson from this week is the gap between those tools and everything else. Browsers can push a revocation within hours. A curl binary, a Python program with its own bundle or a container image built last month cannot, so each of them needs a new trust store, a rebuild or a restart. Dennis Jackson's tracker lists patched versions in a table that shows the spread: Go 1.27.3 and 1.26.10, NSS 3.131.1, Python certifi 2026.10.19, Rust rustls-webpki 0.103.16 and Electron 44.9.1, 43.8.1 and 42.11.16, with Node.js, Bun and FreeBSD still marked pending when we read it.

A worked example: looking at a chain yourself

You can see the path your own machine is given. The command below connects to a site and prints every certificate the server sends, which is usually the site's certificate followed by one or more intermediates:

openssl s_client -connect example.com:443 -servername example.com -showcerts

In the output, each certificate has a subject (s:) and an issuer (i:). Read it from the top: the first certificate's issuer is the second certificate's subject, and so on, until you reach a certificate whose issuer is a root that your trust store already contains. That match is the "name chaining" RFC 5280 describes. The root itself is normally not sent by the server, because the client is expected to have it.

Two things follow. First, the server must send the right intermediates; a missing one is a common cause of "unable to get local issuer certificate" errors, and the fix is on the server, not in disabling verification. Second, the intermediates in that list are exactly the certificates a revocation list can name. In the eMudhra case the affected intermediates were issued under the Comodo AAA Services root and the emSign ECC Root CA - G3, according to the tracker, which is why its manual workarounds for systems without a patch remove those two roots (and the tracker marks that route for expert users only).

Check your own systems, step by step

  1. Find out which trust store each tool uses. For curl, its documentation says verification is on by default, the default store is set when curl is built, and CURL_CA_BUNDLE, SSL_CERT_FILE and SSL_CERT_DIR can point it elsewhere. On Apple platforms its behaviour differs depending on the TLS backend. The tracker page says macOS's built-in /usr/bin/curl reads /etc/ssl/cert.pem, which was not updated and does not check revocation.

  2. Test with the researchers' endpoints. The tracker site publishes two test hosts, dv-g3b-emudhra.we-have-a-problem.com and dv-g3b-aaa-emudhra.we-have-a-problem.com. If a client reports a certificate error when it connects, it does not trust the compromised intermediates, which is the result you want. Try the real application path: Cloudflare warns that a passing browser test does not prove a background service is safe, and a curl test does not prove an application that uses a different verifier is safe.

    curl -sS https://dv-g3b-emudhra.we-have-a-problem.com
    
  3. Update the packages. On Debian-based systems, update ca-certificates; in Python, upgrade certifi and any package that bundles roots (python -c "import certifi; print(certifi.where())" shows which bundle is in use); in Go, rebuild with a fixed toolchain; for containers, rebuild images from updated bases and redeploy.

  4. Reload or restart. A long-running service may have loaded its trust store at start-up. Cloudflare's guidance is to confirm whether each application needs a reload, restart or redeployment.

  5. Never switch verification off to make an error go away. curl's own documentation says to "never skip verification in production". Cloudflare gives the same warning about the errors you may see after patching: disabling verification removes the protection the update is meant to restore.

What to remember

  • A certificate is only as trustworthy as every key above it in the chain, including intermediates.
  • Revocation is the weak point of the system, which is why browsers keep fast, central lists such as OneCRL and CRLSets.
  • Most of the cleanup falls on software that keeps its own trust store: language runtimes, containers, embedded devices and command-line tools.
  • Updating an SDK is not the same as updating the verifier beneath it.

Sources

Written by

audiotale.net team

The official account of the people who run audiotale.net: announcements, conversation starters and the newsroom's drafts. Posts written with AI say so. Every other account here is a real person.