Skip to content

Long-Term Validation

Pro — Commercial License Required
Long-Term Validation (LTV) yêu cầu package Pro.

LTV đảm bảo chữ ký vẫn xác minh được sau khi chứng chỉ hết hạn hoặc dịch vụ thu hồi ngừng hoạt động bằng cách nhúng mọi dữ liệu validation vào PDF qua Document Security Store (DSS).

Class LTV

ClassMục đích
LtvManagerĐiều phối xây dựng chain, tải OCSP/CRL, tổ hợp DSS
DssBuilderXây dựng dictionary DSS với cert, OCSP, CRL
OcspClientTải OCSP response (RFC 6960)
CrlFetcherTải CRL từ distribution point (RFC 5280)

LtvManager

Tại cấp B-LT hoặc B-LTA, LtvManager chạy tự động bên trong DigitalSigner. Để kiểm soát thủ công:

php
use Yeeefang\TcpdfNext\Pro\Security\Ltv\LtvManager;

$ltv = new LtvManager($pdf);
$ltv->addCertificate(file_get_contents('/certs/intermediate.pem'));
$ltv->addCertificate(file_get_contents('/certs/root.pem'));
$ltv->addOcspResponse($ocspResponseDer);
$ltv->addCrl($crlDer);
$ltv->apply(); // xây dựng và nhúng dictionary DSS

DssBuilder

Xây dựng dictionary DSS (ISO 32000-2) chứa /Certs, /OCSPs, /CRLs và entry /VRI tùy chọn theo chữ ký.

php
use Yeeefang\TcpdfNext\Pro\Security\Ltv\DssBuilder;

$dss = new DssBuilder();
$dss->addCertificate($intermediateDer);
$dss->addOcspResponse($ocspDer);
$dss->addCrl($crlDer);
$dss->addVri($sigHash, [$signerDer], [$ocspDer], [$crlDer]); // VRI tùy chọn theo chữ ký
$dssDict = $dss->build();

OcspClient

Truy vấn OCSP responder để kiểm tra trạng thái thu hồi chứng chỉ.

php
use Yeeefang\TcpdfNext\Pro\Security\Ltv\OcspClient;

$ocsp = new OcspClient();
$ocsp->timeout(10);
$ocsp->cacheDir('/tmp/ocsp-cache');

$response = $ocsp->query(
    certificate:  '/certs/signing.pem',
    issuer:       '/certs/intermediate.pem',
    responderUrl: 'https://ocsp.example.com', // tùy chọn; trích xuất từ AIA nếu bỏ qua
);

echo $response->status();     // 'good', 'revoked', hoặc 'unknown'
echo $response->producedAt(); // DateTimeImmutable
$derBytes = $response->toDer();

CrlFetcher

Tải CRL từ CDP khai báo trong chứng chỉ, với cache đĩa tùy chọn.

php
use Yeeefang\TcpdfNext\Pro\Security\Ltv\CrlFetcher;

$fetcher = new CrlFetcher();
$fetcher->cacheDir('/tmp/crl-cache');
$fetcher->cacheTtl(86400); // 24 giờ

$crl = $fetcher->fetchForCertificate('/certs/signing.pem');
echo $crl->issuerDN();
echo $crl->revokedCount();
$crl->isRevoked('01:AB:CD:EF'); // bool
$derBytes = $crl->toDer();

Xây dựng Certificate Chain

LtvManager theo extension AIA caIssuers để khám phá intermediate tự động. Nếu HTTP ra ngoài bị hạn chế, cung cấp chain thủ công qua CertificateInfo::chain().

php
$ltv = new LtvManager($pdf);
$ltv->buildChain(signerCertificate: '/certs/signing.pem');
$chain = $ltv->chain(); // mảng chứng chỉ mã hóa DER

Vòng lưu trữ (B-LTA)

B-LTA thêm document timestamp sau khi nhúng DSS. Re-timestamp trước khi chứng chỉ TSA hết hạn để duy trì hiệu lực vô thời hạn:

Ký (B-B) -> TSA timestamp (B-T) -> DSS (B-LT) -> Document timestamp (B-LTA)
    -> [re-timestamp trước khi hết hạn]
php
$ltv = LtvManager::load('/archive/contract-2026.pdf');
$ltv->retimestamp(new TsaClient('https://tsa.example.com/timestamp'));
$ltv->save('/archive/contract-2026.pdf');

Xử lý lỗi

Thao tác LTV throw exception có kiểu: OcspException (responder không truy cập được), CrlException (tải thất bại), hoặc ChainBuildException (chain không đầy đủ). Tất cả nằm dưới namespace Yeeefang\TcpdfNext\Pro\Security\Ltv.

Bước tiếp theo

Phân phối theo giấy phép LGPL-3.0-or-later.