Skip to content

Latest commit

 

History

History
125 lines (89 loc) · 5.75 KB

File metadata and controls

125 lines (89 loc) · 5.75 KB

AuthRoot-style anchors on Linux

Windows resolves Authenticode chains against machine/user certificate stores plus Microsoft Authenticode roots. On Linux/macOS, portable trust verification can use explicit roots, or it can automatically download and cache Microsoft’s authrootstl.cab when no explicit roots are supplied.

By default, psign-tool portable trust-verify-* and bare psign-tool --mode portable verify download authrootstl.cab from Microsoft’s Windows Update distribution URL when the cache is missing or stale. The cache lives at ~/.psign/authroot/authrootstl.cab with metadata in authrootstl.cab.json. The default refresh window is 7 days.

Set PSIGN_NO_AUTO_TRUST=1 (also accepts true or yes) to disable automatic AuthRoot use. Set PSIGN_AUTHROOT_MAX_AGE_DAYS=<days> to change the staleness window. Advanced/offline environments can set PSIGN_AUTHROOT_CACHE_DIR or PSIGN_AUTHROOT_URL for an alternate cache location or mirror. Explicit --authroot-cab, --anchor-dir, or repeatable --trusted-ca inputs take precedence and suppress automatic AuthRoot resolution.

Phase A — anchor directory (recommended first ship)

  1. On a Windows machine with updates, sync roots you trust, for example:
    • certutil -generateSSTFromWU roots.sst then export, or
    • Copy known .crt / .cer files into a folder (repo-local or CI cache).
  2. Pass --anchor-dir /path/to/certs to trust-verify-pe, or pass individual files with repeatable --trusted-ca /path/to/root.cer.
    Non-recursive: only *.crt, *.cer, *.pem in that directory are loaded.
  3. Thumbprints are SHA-1 over full certificate DER (same convention as many Windows tools), not TBSCertificate-only.

Keep separate what you trust as an anchor vs what happens to be embedded in the PE (intermediates are usually present in the signature).

Phase B — authrootstl.cab extraction

psign-authenticode-trust reads a Microsoft authrootstl.cab, walks *.stl entries, and:

  1. Harvests X.509 certificates from PKCS#7 blobs (Pkcs7::from_der on each member).
  2. Parses PKCS#7 ContentInfoSignedData when present and extracts CTL eContent TrustedSubject SHA-1 SubjectIdentifier octets into the anchor thumbprint set (alongside cert-derived thumbs).

Pass --authroot-cab /path/to/authrootstl.cab on any trust-verify-* subcommand to use a pinned or mirrored CAB instead of the automatic cache.

Bootstrap integrity

  • CI / reproducibility: pin a SHA-256 of the CAB; pass --authroot-cab and --expect-authroot-cab-sha256 <64-hex> so ingest aborts on mismatch.
  • Future hardening: verify the outer Authenticode signature / CTL semantics on the STL (see technical plan).

Examples

Default portable trust using the automatic AuthRoot cache:

psign-tool portable trust-verify-pe ./signed.exe

Bare portable verify also routes to trust verification for supported formats when auto trust is enabled:

psign-tool --mode portable verify ./signed.exe
psign-tool portable trust-verify-pe \
  --anchor-dir ./my-trusted-roots \
  ./signed.exe

Single-file non-admin trust anchor:

psign-tool portable trust-verify-pe \
  --trusted-ca ./test-root.cer \
  ./signed.exe

The unified CLI uses the same trust path without writing to the Windows or Linux OS trust store. With --mode portable verify, supported formats route to the corresponding portable trust-verify-* command by default when automatic AuthRoot is enabled. Explicit trust inputs such as --trusted-ca, --anchor-dir, --authroot-cab, AIA/OCSP/CRL flags, and timestamp policy flags still route to the same trust commands:

psign-tool --mode portable verify \
  --trusted-ca ./test-root.cer \
  ./signed.exe

With Microsoft root harvest from CAB:

psign-tool --mode portable verify \
  --authroot-cab ./authrootstl.cab \
  --anchor-dir ./extra-enterprise-roots \
  --verbose-chain \
  ./signed.exe

Strict code signing EKU is default; for diagnostics only:

psign-tool portable trust-verify-pe --allow-loose-signing-cert ...

Expired corpora / reproducible CI: pin verification instant:

psign-tool portable trust-verify-pe --anchor-dir ./roots --as-of 2023-07-01 ./fixture.exe

For local online issuer tests, enable bounded in-memory AIA fetching. Only HTTP AIA URLs are currently supported, intended for loopback psign-server tests:

psign-tool portable trust-verify-pe \
  --trusted-ca ./test-root.cer \
  --online-aia \
  ./signed-with-missing-intermediate.exe

For local CRL revocation tests, use strict revocation with an explicit loopback CRL URL. The CRL is fetched into memory, checked against the issuing CA signature, and evaluated for revoked signer/intermediate serials without touching OS stores:

psign-tool portable trust-verify-detached \
  ./content.bin ./signature.p7 \
  --trusted-ca ./test-root.cer \
  --revocation-mode require \
  --crl-url-override http://127.0.0.1:5000/crl.der

OCSP loopback tests use the same revocation policy. The portable verifier sends a bounded OCSP request, verifies the BasicOCSPResponse signature with the issuing CA, and applies good/revoked/unknown status:

psign-tool portable trust-verify-detached \
  ./content.bin ./signature.p7 \
  --trusted-ca ./test-root.cer \
  --revocation-mode require \
  --online-ocsp \
  --ocsp-url-override http://127.0.0.1:5000/ocsp

Related docs