Skip to content

Time-Stamp Authority (TSA)

This guide covers the RFC 3161 compliant timestamping server implementation.

A Time-Stamp Authority (TSA) provides cryptographic proof that data existed at a specific time. QPKI implements an RFC 3161 compliant timestamping server with post-quantum algorithm support via RFC 9882.

StandardDescription
RFC 3161Time-Stamp Protocol (TSP)
RFC 5652Cryptographic Message Syntax (CMS)
RFC 5816ESSCertIDv2 Update for RFC 3161
RFC 9882ML-DSA in CMS
FIPS 204ML-DSA (Dilithium)
FIPS 205SLH-DSA (SPHINCS+)
eIDASEU 910/2014 Electronic Identification and Trust Services
ETSI EN 319 422Time-stamping protocol profiles for eIDAS
FormatExtensionContent-Type
TimeStampReq.tsqapplication/timestamp-query
TimeStampResp.tsrapplication/timestamp-reply
┌─────────────────────────────────────────────────────────────────────┐
│ TSA Server │
├─────────────────────────────────────────────────────────────────────┤
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────┐ │
│ │ HTTP Handler │────│ Timestamper │────│ Signing │ │
│ │ (POST) │ │ (RFC 3161) │ │ Key │ │
│ └──────────────────┘ └──────────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────┘

Token Contents:

  • Serial number (unique identifier)
  • Generation time (UTC)
  • Message imprint (hash of timestamped data)
  • TSA policy OID
  • Optional: nonce, accuracy

Sign a file with a timestamp.

Terminal window
# Sign with credential (recommended)
qpki tsa sign --data document.pdf --credential tsa --out token.tsr
qpki tsa sign --data document.pdf --cert tsa.crt --key tsa.key --out token.tsr
# --credential <id> Credential ID (alternative to --cert/--key)
# --hash sha256|sha384|sha512 Hash algorithm (default: sha256)
# --include-tsa Include TSA name in token

Verify a timestamp token.

Terminal window
qpki tsa verify --token token.tsr --data document.pdf --ca ca.crt
qpki tsa verify --token token.tsr --ca ca.crt

Display token information.

Terminal window
qpki inspect token.tsr

Output:

Timestamp Response:
Status: granted
Timestamp Token:
Version: 1
Serial Number: 123456789012345678901234567890
Gen Time: 2025-01-15T10:30:00Z
Policy: 1.3.6.1.4.1.99999.2.1
Message Imprint:
Hash Alg: 2.16.840.1.101.3.4.2.1
Hash: AB:CD:EF:...
Accuracy: 1s 0ms 0us
Nonce: 12345

Create a timestamp request.

Terminal window
qpki tsa request --data document.pdf --out request.tsq
qpki tsa request --data document.pdf --nonce --out request.tsq
qpki tsa request --data document.pdf --hash sha384 --out request.tsq

Options:

FlagDescriptionDefault
--dataFile to timestampRequired
--hashHash algorithm (sha256, sha384, sha512)sha256
--nonceInclude random noncefalse
-o, --outOutput fileRequired

Display timestamp token information.

Terminal window
qpki tsa info token.tsr

Output:

Timestamp Token:
Version: 1
Serial Number: 123456789012345678901234567890
Gen Time: 2025-01-15T10:30:00Z
Policy: 1.3.6.1.4.1.99999.2.1
Message Imprint:
Hash Alg: SHA-256
Hash: AB:CD:EF:...
Accuracy: 1s
Signer: CN=tsa.example.com

Start an HTTP TSA server.

Terminal window
# Start the server with credential (recommended)
qpki tsa serve --port 8318 --credential tsa
qpki tsa serve --port 8318 --cert tsa.crt --key tsa.key
qpki tsa serve --port 8318 --cert tsa.crt --key tsa.key --pid-file /var/run/tsa.pid
# --credential <id> Credential ID (alternative to --cert/--key)
# --policy "1.3.6.1.4.1.X.Y.Z" TSA policy OID
# --tls-cert server.crt TLS certificate (HTTPS)
# --pid-file /path/to/file.pid PID file path

Options:

FlagDescriptionDefault
--portHTTP port8318
--certTSA certificateRequired
--keyTSA private keyRequired
--hsm-configHSM configuration file-
--key-labelHSM key label (CKA_LABEL)-
--key-idHSM key ID (CKA_ID, hex)-
--policyTSA policy OID1.3.6.1.4.1.99999.2.1
--accuracyAccuracy in seconds1
--tls-certTLS certificate (HTTPS)-
--tls-keyTLS key (HTTPS)-
--pid-filePID file path/tmp/qpki-tsa-{port}.pid

Stop a running TSA server.

Terminal window
# Stop using default PID file (based on port)
qpki tsa stop --port 8318
qpki tsa stop --pid-file /var/run/tsa.pid

Options:

FlagDescriptionDefault
--portPort to derive default PID file8318
--pid-filePID file path/tmp/qpki-tsa-{port}.pid

Note: The stop command sends a SIGTERM signal to the process. This works on Unix-like systems (Linux, macOS) but not on Windows.

ElementValue
MethodPOST
Endpoint/
Content-Type (request)application/timestamp-query
Content-Type (response)application/timestamp-reply

Terminal window
# ECDSA
qpki credential enroll --ca-dir ./ca --cred-dir ./credentials \
--profile ec/timestamping --var cn=tsa.example.com --id tsa
qpki credential enroll --ca-dir ./ca --cred-dir ./credentials \
--profile ml/timestamping --var cn=pqc-tsa.example.com --id pqc-tsa
qpki credential enroll --ca-dir ./ca --cred-dir ./credentials \
--profile slh/timestamping --var cn=archive-tsa.example.com --id archive-tsa
qpki credential enroll --ca-dir ./ca --cred-dir ./credentials \
--profile hybrid/catalyst/timestamping --var cn=hybrid-tsa.example.com --id hybrid-tsa
qpki tsa serve --port 8318 \
--cert ./credentials/tsa/tsa.crt --key ./credentials/tsa/tsa.key
Terminal window
# 1. Generate key
qpki key gen --algo ecdsa-p256 --out tsa.key
qpki csr create --key tsa.key --cn tsa.example.com --out tsa.csr
qpki cert issue --ca-dir ./ca --profile ec/timestamping --csr tsa.csr --out tsa.crt
qpki tsa serve --port 8318 --cert tsa.crt --key tsa.key

Using credentials for tsa serve enables zero-downtime certificate rotation via the rotate → activate workflow:

Terminal window
# 1. Start server with credential
qpki tsa serve --port 8318 --credential tsa
qpki credential rotate tsa
qpki credential versions tsa
qpki credential activate tsa --version v2

The server always uses the active version of the credential. This workflow allows:

  • Certificate renewal without service interruption
  • Gradual rollout with rollback capability
  • Crypto-agility migration (add/remove algorithm profiles)

Terminal window
# Generate a request
openssl ts -query -data document.pdf -sha256 -out request.tsq
curl -H "Content-Type: application/timestamp-query" \
--data-binary @request.tsq \
http://localhost:8318/ -o response.tsr
openssl ts -verify -in response.tsr -data document.pdf -CAfile ca.crt

Note: OpenSSL does not support ML-DSA/SLH-DSA. Use qpki tsa verify for PQC tokens.


Terminal window
# 1. Sign the code
codesign --sign "Developer ID" myapp.app
qpki tsa sign --data myapp.app/Contents/_CodeSignature/CodeResources \
--cert tsa.crt --key tsa.key --out myapp.tsr
Terminal window
# Use SLH-DSA for maximum quantum resistance
qpki credential enroll --profile slh/timestamping \
--var cn=archive-tsa.example.com --id archive-tsa
for doc in *.pdf; do
qpki tsa sign --data "$doc" --cert archive-tsa.crt --key archive-tsa.key \
--out "${doc%.pdf}.tsr"
done

QPKI supports eIDAS qualified electronic timestamps (EU Regulation 910/2014).

StandardDescription
eIDASEU Regulation 910/2014 on electronic identification and trust services
ETSI EN 319 422Time-stamping protocol and token profiles
ETSI EN 319 412-5QCStatements extension for qualified certificates

For a timestamp to be considered qualified under eIDAS:

  1. TSA Certificate: Must contain QCStatements with qcCompliance
  2. Token Extension: Must include esi4-qtstStatement-1 (OID 0.4.0.19422.1.1)
  3. SigningCertificateV2: Must include ESSCertIDv2 attribute (RFC 5816)

When the TSA certificate contains the qcCompliance QCStatement, QPKI automatically adds the esi4-qtstStatement-1 extension to the TSTInfo:

TSTInfo:
version 1
policy 0.4.0.2042.1.3
messageImprint ...
serialNumber ...
genTime 2025-01-21T10:30:00Z
extensions:
- esi4-qtstStatement-1 (0.4.0.19422.1.1) <-- Added automatically
Terminal window
# Create eIDAS qualified TSA certificate
qpki credential enroll --profile eidas/qc-tsa \
--var cn="ACME Qualified TSA" \
--var organization="ACME Corporation" \
--var country="FR" \
--id qualified-tsa

The eidas/qc-tsa profile includes:

  • QCStatements with qcCompliance
  • extKeyUsage: timeStamping (critical, exclusive per RFC 3161)
  • ETSI policy OID 0.4.0.2042.1.3
Terminal window
# Start qualified TSA server
qpki tsa serve --port 8318 \
--cert qualified-tsa.crt \
--key qualified-tsa.key \
--policy "0.4.0.2042.1.3"
curl -H "Content-Type: application/timestamp-query" \
--data-binary @request.tsq \
http://localhost:8318/ -o qualified-response.tsr
Terminal window
# Inspect token to verify esi4-qtstStatement-1 extension
qpki inspect qualified-response.tsr

Expected output includes:

Extensions:
- OID: 0.4.0.19422.1.1 (esi4-qtstStatement-1)
Critical: false

TSA signing operations support HSM-stored keys.

Terminal window
export HSM_PIN="****"
# Sign timestamp with HSM key
qpki tsa sign --data document.pdf --cert tsa.crt \
--hsm-config ./hsm.yaml --key-label "tsa-key" --out token.tsr
# Start TSA server with HSM key
qpki tsa serve --port 8318 --cert tsa.crt \
--hsm-config ./hsm.yaml --key-label "tsa-key"

See HSM Integration for configuration details.


  • CMS - CMS signatures and encryption
  • Credentials - TSA credentials
  • HSM - Hardware Security Module integration
  • RFC 3161 - Time-Stamp Protocol
  • RFC 9882 - ML-DSA in CMS