ca-trust(8)
NAME
ca-trust - build the system TLS CA trust store
SYNOPSIS
ca-trust generate [--root DIR] [--force] [--dry-run] [--keep N]
ca-trust check [--root DIR] [--strict]
ca-trust [-h | --help] [-V | --version]
DESCRIPTION
Every TLS client on the system reads the same set of trusted CA certificates. That set is built from a few source directories, and somebody has to rebuild it whenever those change. If the rebuild dies halfway, or a reader catches it halfway, you get a system that trusts nothing, or trusts the wrong things. That's bad.
ca-trust is that rebuild, and it publishes the result in one step. It does no certificate parsing of its own. p11-kit is the trust authority, and ca-trust execs trust(1) to do the extraction. What ca-trust owns is the part p11-kit doesn't: deciding when the store needs rebuilding, and swapping it into place so that nothing ever reads a half-written store.
How does the swap work?
Each build lands in its own directory, /var/lib/ca-trust/store-<id>/. The <id> is a sha256 digest of the tree itself, so the name is the content. Then the live symlink is repointed onto it with a rename, which POSIX makes atomic. A reader either sees the old store or the new one. Never a mix.
Everything that can fail happens before that rename. If any of it fails, live stays where it was, so a broken run is a no-op rather than a broken trust store.
Because the id is the content, a rebuild that produces the same bytes is recognised as such. generate reports unchanged and leaves live alone.
What if the result is empty?
Then it's refused, not published. An empty or incomplete store is the signature of a misfired source redirect, and pushing it live would make every TLS connection on the box fail. Not even --force gets it through.
A complete store has all three outputs listed under FILES, and none of them empty.
Do I need root?
On a live system, yes. generate must run as root, and it never drops privileges, so the trust bytes stay root-owned end to end. Running it unprivileged without --root is refused:
ca-trust: must run as root to build the live trust store; pass --root <dir> to build a staged tree unprivileged
To build a store for a tree you own -- an image being composed, say -- run it unprivileged, with --root. As root, --root is refused too. p11-kit ignores user configuration as root, so it would read the host's certificates instead of the tree's. To get a store into a tree as root, install into it with pkg install --root, whose trigger builds the store inside it.
check without --strict only reads, so anyone can run it. check --strict recomputes the store, so the same rules as for generate apply.
COMMANDS
generateExtract anchors via p11-kit and atomically repoint live. Run it after changing anything under the source directories listed in FILES. Running it again with nothing changed does nothing.
It prints one line saying what happened, for example
swapped: live -> store-<id> (newly built), orunchanged: live already store-<id>.Concurrent runs serialize on a flock(2) of /var/lib/ca-trust itself. There's no lock file. A second
generatewaits until the first finishes, because a run that swapped last with an older trust set would undo the newer one.--dry-runtakes no lock.check- Verify that live resolves to a complete store, and print the id it resolves to. It never writes anything. With
--strictit also recomputes the store from the current sources, and fails if live is out of date.
OPTIONS
--rootDIR- Treat DIR as
/for both sources and destination, instead of the running system. Unprivileged only.ca-trustwrites a transient p11-kit user configuration naming the relocated sources, so stock p11-kit needs no configuration of its own. As root this is refused, since p11-kit would ignore that configuration and read the host's anchors. --force- (generate) Repoint live even when the freshly built store is identical to the one already live. It doesn't relax the completeness check.
--dry-run- (generate) Build the store in a temporary directory, compute its id, report whether a real run would swap, and write nothing under /var/lib/ca-trust.
--keepN- (generate) Keep the N most recently modified previous store directories around for rollback. The live store is always kept, and doesn't count against N. Default
1. --strict- (check) Also recompute the store from the current sources, and fail if it differs from what is live. In other words: fail if the store is stale.
-h,--help- Print usage and exit. Running
ca-trustwith no arguments does the same. -V,--version- Print the program name and version and exit. Accepted before or after a subcommand.
EXIT STATUS
0- Success. For
check: live exists and is complete, and with--strictit's also up to date. 1- Failure, with the reason on standard error. For
checkthis covers a missing, dangling or incomplete live, as well as a--strictrun that finds the store stale.
FILES
Sources
- /usr/share/pki/ca-trust-source/anchors/
- Certificates to trust, shipped by the distribution.
- /usr/share/pki/ca-trust-source/blocklist/
- Certificates to reject, shipped by the distribution.
- /etc/pki/ca-trust/source/anchors/
- Certificates the administrator adds.
- /etc/pki/ca-trust/source/blocklist/
- Certificates the administrator rejects.
These four are p11-kit-trust's own compiled-in source directories, operator before vendor, so on a live root system p11-kit finds them with no configuration at all. Whether a distribution fills them with real files or with symlinks out of its own CA package is that package's business, not this tool's.
Output
- /var/lib/ca-trust/store-<id>/
- A built store, named for the digest of its own contents.
- /var/lib/ca-trust/live
- Symlink to the current store. Programs read through this.
- /var/lib/ca-trust/live/ca-roots.pem
- Every trusted anchor in one PEM bundle.
- /var/lib/ca-trust/live/certs/
- The same anchors one per file, hashed-directory style.
- /var/lib/ca-trust/live/openssl/
- Anchors plus the reject list, in OpenSSL's directory format.
ENVIRONMENT
CA_TRUST_SOURCE_DIRS- Colon-separated list of absolute source directories, replacing the compiled-in defaults above. For a p11-kit built with different defaults, and for testing. A relative entry is an error.
CA_TRUST_TRUST_BIN- The p11-kit
trustexecutable to run. Defaults to/usr/bin/trust.PATHis not searched. CA_TRUST_MODULE- Path to the
p11-kit-trust.somodule, for the unprivileged--rootpath where a p11-kit user configuration is written. Used when it exists; otherwise the usual module locations are tried. SOURCE_DATE_EPOCH- Passed through to trust(1) for reproducible output.
The extraction otherwise runs with a cleared environment: only PATH is kept, and LC_ALL is set to C.
The CA_TRUST_* overrides are trusted like the rest of the caller's environment. A caller who sets them for root is already root. Package triggers run ca-trust with a fixed environment, so a trigger never carries them.
EXAMPLES
You added a certificate and want the system to trust it:
cp mycorp-root.crt /etc/pki/ca-trust/source/anchors/ ca-trust generate
Is the store up to date? Ask without touching it:
ca-trust check --strict
Without --strict, check only looks at live:
$ ca-trust check ok: live -> store-749c128fb80aa630...9c3ab9eda54dc8c3
See what a rebuild would do, without doing it:
ca-trust generate --dry-run
Build a store for an image being composed, unprivileged:
ca-trust generate --root image/
Keep more history to roll back through:
ca-trust generate --keep 5
NOTES
ca-trust needs p11-kit at run time: the trust(1) command and the p11-kit-trust.so module. Nothing else.
SEE ALSO
trust(1), p11-kit(8), update-ca-trust(8), openssl(1)
AUTHOR
Auke Kok <sofar@foo-projects.org>