. "$BST_LIB" # ca-certificates is data only -- the Mozilla NSS root-CA set, plus the # concatenated bundle and the hashed-symlink store an OpenSSL CApath walk needs. # There is no tool to `require`: what ships is the TRUST STORE, and the contract # this suite asserts is that it is COMPLETE AND SELF-CONSISTENT AS SHIPPED, # because nothing regenerates it on target. The store is produced offline by the # host's openssl and run-parts under do_rootfs (PACKAGE_WRITE_DEPS), the deployed # rootfs is read-only at browser runtime, and the target has no openssl to rehash # with (BRINTOS-295) -- so a store that arrives half-built stays half-built, and # every case below is a check that the offline generation actually finished. # --- the anchors themselves ------------------------------------------------- check ca-certificates/certsdir test -d /usr/share/ca-certificates/mozilla n_crt=$(find /usr/share/ca-certificates -type f -name '*.crt' | wc -l) if [ "$n_crt" -ge 100 ]; then bst_ok ca-certificates/anchor-count else bst_notok ca-certificates/anchor-count "only $n_crt *.crt under /usr/share/ca-certificates"; fi # The trust list: one enabled line per anchor the bundle must carry. check ca-certificates/conf test -s /etc/ca-certificates.conf check_out ca-certificates/conf-mozilla "mozilla/" sh -c "grep -m1 '^mozilla/' /etc/ca-certificates.conf" # --- the concatenated bundle (OpenSSL CAfile shape) ------------------------- check ca-certificates/bundle test -s /etc/ssl/certs/ca-certificates.crt check_out ca-certificates/bundle-pem "-----BEGIN CERTIFICATE-----" \ head -c 4096 /etc/ssl/certs/ca-certificates.crt n_bundle=$(grep -c -- '-----BEGIN CERTIFICATE-----' /etc/ssl/certs/ca-certificates.crt) if [ "$n_bundle" -ge 100 ]; then bst_ok ca-certificates/bundle-count else bst_notok ca-certificates/bundle-count "bundle carries only $n_bundle certificates"; fi # Completeness, not just plausibility: the bundle must carry exactly as many # certificates as ca-certificates.conf enables. A postinst that died partway # through would leave these two numbers apart. n_conf=$(sed -e '/^$/d' -e '/^#/d' -e '/^!/d' /etc/ca-certificates.conf | wc -l) check_eq ca-certificates/bundle-complete "$n_conf" "$n_bundle" # A postinst that failed after writing its temp bundle leaves this behind. check ca-certificates/no-partial test ! -e /etc/ssl/certs/ca-certificates.crt.new # --- /etc/ssl/cert.pem (the /cert.pem convention) --------------- # A static port binary built --openssldir=/etc/ssl reads its default CAfile here # (linux-in-the-browser#94's wget); the bbappend symlinks it to the same bundle. check ca-certificates/cert-pem test -e /etc/ssl/cert.pem check ca-certificates/cert-pem-same cmp -s /etc/ssl/cert.pem /etc/ssl/certs/ca-certificates.crt # --- the hashed store (OpenSSL CApath shape) -------------------------------- # X509_LOOKUP_hash_dir looks up <8-hex-subject-hash>.; oe-core's openssl # points SSL_CERT_DIR at this directory, so on an OE-configured openssl THIS is # the load-bearing store rather than the bundle. n_hash=$(ls /etc/ssl/certs 2>/dev/null | grep -c '^[0-9a-f]\{8\}\.[0-9]$') if [ "$n_hash" -ge 100 ]; then bst_ok ca-certificates/hash-count else bst_notok ca-certificates/hash-count "only $n_hash hashed symlinks in /etc/ssl/certs"; fi # Per-anchor .pem symlinks, and every symlink in the store resolving. `-e` # follows the link, so a dangling one is caught whichever name form it carries. n_pem=$(ls /etc/ssl/certs 2>/dev/null | grep -c '\.pem$') if [ "$n_pem" -ge 100 ]; then bst_ok ca-certificates/pem-count else bst_notok ca-certificates/pem-count "only $n_pem .pem symlinks in /etc/ssl/certs"; fi dangling=$(find /etc/ssl/certs -type l ! -exec test -e {} \; -print 2>/dev/null | wc -l) check_eq ca-certificates/no-dangling "0" "$dangling" # --- the precondition the anchors depend on -------------------------------- # Certificate validity is a wall-clock comparison, and the guest's CLOCK_REALTIME # is seeded from the browser host's Date.now(). A wrong clock makes every anchor # useless in one direction or the other, so the store's meaning rests on this. y=$(date -u +%Y) if [ "$y" -ge 2026 ] && [ "$y" -le 2100 ]; then bst_ok ca-certificates/wallclock else bst_notok ca-certificates/wallclock "guest wall clock reports year $y"; fi # --- the updater ships, and is not the maintenance path --------------------- # It is a #!/bin/sh script: directly runnable since linux-in-the-browser#75, so # --help (which returns before the script touches anything) proves both the # shebang exec path and that the script arrived intact. It cannot MAINTAIN the # store here -- `openssl rehash` is absent and the rootfs is read-only -- which # is why every case above asserts the shipped store instead of regenerating it. if command -v update-ca-certificates >/dev/null 2>&1; then check_out ca-certificates/updater-help "--fresh" update-ca-certificates --help else bst_skip ca-certificates/updater-help "update-ca-certificates not installed on this image" fi # --- is the store WIRED, or merely present? --------------------------------- # Every case above proves the store was BUILT correctly; none of them proves a # consumer can FIND it -- the "shipped anchors nobody reads" failure, which is # silent by construction. openssl (BRINTOS-295) is this image's first trust-store # consumer, so ask it: a self-signed root that IS in the store must verify # against the DEFAULT paths (SSL_CERT_DIR -> /usr/lib/ssl-3/certs -> # /etc/ssl/certs), and the SAME root must FAIL with the defaults switched off. # The negative control is what gives the positive meaning -- without it, "OK" # could just as well mean openssl was lenient about a self-signed certificate. if command -v openssl >/dev/null 2>&1; then anchor=$(ls /etc/ssl/certs/*.pem 2>/dev/null | head -1) if [ -n "$anchor" ]; then check_out ca-certificates/default-store-verify "OK" openssl verify "$anchor" if openssl verify -no-CAfile -no-CApath "$anchor" >/dev/null 2>&1; then bst_notok ca-certificates/default-store-control \ "verify still passed with the default store OFF -- the OK above proves nothing" else bst_ok ca-certificates/default-store-control fi else bst_notok ca-certificates/default-store-verify "no anchor .pem in /etc/ssl/certs to verify against" fi # Recorded, not relied on: on-target regeneration is deliberately not this # store's maintenance path, and openssl-misc (which carries the c_rehash perl # script) is not installed. Whether the built-in subcommand exists is worth # knowing for anyone who reaches for it. if openssl rehash -help >/dev/null 2>&1; then bst_ok ca-certificates/rehash-subcommand else bst_skip ca-certificates/rehash-subcommand "no openssl rehash; unused -- the store is generated offline" fi else bst_skip ca-certificates/default-store-verify "no openssl on this image; nothing here reads a trust store yet" fi