Verifying a timestamp

Every token embeds its own signing chain, so verification is a self-contained cryptographic check once you have the data and a trusted root. Policy and revocation information are published separately. The steps below work on .tsr responses from either TSA endpoint; use the files created in Getting started or replace their names with yours.

1. Decode the token

openssl ts -reply -in report.pdf.tsr -text

This shows the status, policy OID, message hash, serial number, generation time, and TSA identity.

2. Check the policy OID

Confirm the OID matches a version listed at tsa.cnx.net.kh/policy.html — see Request and token format for what the current OID is and why an older token can legitimately carry a different one.

3. Extract the chain

openssl ts -reply -in report.pdf.tsr -token_out \
  | openssl pkcs7 -inform DER -print_certs > chain.pem

chain.pem contains the signer, TSA intermediate, and root CA certificates. Identify the CNX root by its subject and issuer, and save its complete PEM certificate block as root.crt. Do not rely on certificate position in the bundle.

4. Pin the root

Don't trust the root certificate in chain.pem on its own — it came from the same response you're verifying. Pin it against the value CNX publishes independently:

# Extract the root's public key and hash it
openssl x509 -in root.crt -pubkey -noout \
  | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256 -binary | base64

# Compare against the DNSSEC-signed published pin
dig +dnssec TXT _ca.cnx.net.kh

See The trust anchor for what's being compared here and why. Use a validating resolver and confirm the AD flag before relying on the DNSSEC-published pin; requesting DNSSEC data alone does not validate the response.

5. Verify

openssl ts -verify -data report.pdf -in report.pdf.tsr \
  -untrusted chain.pem -CAfile root.crt

Verification: OK confirms the response signature and chain against your pinned root and the hash of the current report.pdf.

If you retained the original query, also check the response against it:

openssl ts -verify -queryfile report.pdf.tsq -in report.pdf.tsr -untrusted chain.pem -CAfile root.crt

This checks the request's imprint and nonce against the response. Keep the original data, request, response, and the trust material used for verification. Use Attesting files and logs for retention patterns in recurring jobs.