Skip to content

Timestamp Authority (TSA)

Pro — Commercial License Required
RFC 3161 TSA integration requires the Pro package.

TCPDF-Next Pro ships a production-grade RFC 3161 Timestamp Authority client (TsaClient) and a DocumentTimestamp helper that embeds /DocTimeStamp signatures for PAdES B-LTA workflows.

TsaClient

Basic Usage

php
use Yeeefang\TcpdfNext\Pro\Tsa\TsaClient;

$tsa = new TsaClient(url: 'https://freetsa.org/tsr');

$token = $tsa->timestamp($pdfHash);

With Authentication

Some enterprise TSA servers require credentials:

php
$tsa = new TsaClient(
    url:      'https://tsa.enterprise.example/rfc3161',
    username: 'api-user',
    password: 'api-secret',
);

RFC 3161 TimeStampReq Construction

The client builds a standards-compliant TimeStampReq ASN.1 structure for every request:

  1. MessageImprint -- SHA-256 digest of the data to be timestamped.
  2. Nonce -- Cryptographically random 64-bit value to prevent replay attacks.
  3. CertReq -- Set to true so the TSA includes its signing certificate in the response.
php
// The hash must be raw binary (32 bytes for SHA-256)
$hash = hash('sha256', $documentBytes, binary: true);

$token = $tsa->timestamp($hash, algorithm: 'sha256');

Nonce Verification

After receiving the TimeStampResp, the client automatically:

  1. Parses the TSTInfo from the response.
  2. Extracts the nonce from the TSTInfo.
  3. Compares it against the nonce sent in the request.
  4. Throws TsaNonceMismatchException if they differ.
php
try {
    $token = $tsa->timestamp($hash);
} catch (\Yeeefang\TcpdfNext\Pro\Tsa\TsaNonceMismatchException $e) {
    // Nonce mismatch -- possible MITM or replay attack
    log_security_event($e->getMessage());
}

PKIStatus Validation

The client validates the PKIStatus field in every response:

CodeMeaningClient Behavior
0grantedToken accepted
1grantedWithModsToken accepted with warning logged
2rejectionTsaRejectedException thrown
3waitingNot supported; exception thrown
4revocationWarningToken accepted with warning logged
5revocationNotificationTsaCertRevokedException thrown

DNS Pinning (SSRF Protection)

To prevent Server-Side Request Forgery, you can pin the TSA hostname to a specific IP address. The client uses CURLOPT_RESOLVE to bypass DNS resolution entirely:

php
$tsa = new TsaClient(
    url: 'https://tsa.enterprise.example/rfc3161',
);

// Pin the hostname to a known IP -- DNS is never queried
$tsa->pinDns('tsa.enterprise.example', '203.0.113.42', port: 443);

This is critical in environments where the TSA URL originates from user input or external configuration and must not resolve to internal network addresses.

mTLS (Mutual TLS)

Enterprise TSA servers frequently require client certificate authentication. Pass your client certificate and private key:

php
$tsa = new TsaClient(
    url: 'https://tsa.bank.example/timestamp',
);

$tsa->clientCertificate(
    certPath: '/etc/pki/tsa-client.pem',
    keyPath:  '/etc/pki/tsa-client.key',
    keyPassword: 'client-key-pass',
);

The underlying cURL handle is configured with CURLOPT_SSLCERT, CURLOPT_SSLKEY, and CURLOPT_SSLCERTPASSWD.

DocumentTimestamp (B-LTA)

DocumentTimestamp adds a /DocTimeStamp signature to the PDF, which is the final step in a PAdES B-LTA workflow. This timestamp covers the entire document including all previous signatures and the DSS (Document Security Store).

php
use Yeeefang\TcpdfNext\Pro\Tsa\DocumentTimestamp;
use Yeeefang\TcpdfNext\Pro\Tsa\TsaClient;

$tsa = new TsaClient(url: 'https://freetsa.org/tsr');

$stamper = new DocumentTimestamp(
    tsaClient: $tsa,
    hashAlgorithm: 'sha256',
);

// Apply the document timestamp (incremental save)
$stamper->apply($document);

B-LTA Workflow Summary

1. Sign document          (PAdES B-B)
2. Add signature timestamp (PAdES B-T)
3. Embed DSS (OCSP + CRL) (PAdES B-LT)
4. Add /DocTimeStamp       (PAdES B-LTA)  <-- DocumentTimestamp
ProviderURLAuthNotes
FreeTSAhttps://freetsa.org/tsrNoneFree; suitable for testing
Sectigohttps://timestamp.sectigo.comNoneProduction-grade; free tier
DigiCerthttps://timestamp.digicert.comNoneWidely trusted
GlobalSignhttps://timestamp.globalsign.com/tsa/r6advanced1NoneSHA-256 default
Custom / EnterpriseVariesBasic, mTLS, BearerUse pinDns() + clientCertificate()

TIP

For production PAdES B-LTA documents, use a TSA provider whose root certificate is in the Adobe Approved Trust List (AATL). This ensures timestamps are recognized by Adobe Acrobat without manual trust configuration.

Released under the LGPL-3.0-or-later License.