Long-Term Validation
O LTV garante que as assinaturas permaneçam verificáveis após a expiração dos certificados ou quando os serviços de revogação ficam offline, incorporando todos os dados de validação no PDF via Document Security Store (DSS).
Classes LTV
| Classe | Finalidade |
|---|---|
LtvManager | Orquestra construção de cadeia, busca OCSP/CRL, montagem DSS |
DssBuilder | Constrói o dicionário DSS com certs, OCSPs, CRLs |
OcspClient | Busca respostas OCSP (RFC 6960) |
CrlFetcher | Baixa CRLs dos pontos de distribuição (RFC 5280) |
LtvManager
Nos níveis B-LT ou B-LTA, o LtvManager é executado automaticamente dentro do DigitalSigner. Para controle manual:
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(); // builds and embeds the DSS dictionaryDssBuilder
Constrói o dicionário DSS (ISO 32000-2) contendo /Certs, /OCSPs, /CRLs e entradas /VRI opcionais por assinatura.
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]); // optional per-signature VRI
$dssDict = $dss->build();OcspClient
Consulta respondedores OCSP para verificar o status de revogação de certificados.
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', // optional; extracted from AIA if omitted
);
echo $response->status(); // 'good', 'revoked', or 'unknown'
echo $response->producedAt(); // DateTimeImmutable
$derBytes = $response->toDer();CrlFetcher
Baixa CRLs do CDP declarado nos certificados, com cache em disco opcional.
use Yeeefang\TcpdfNext\Pro\Security\Ltv\CrlFetcher;
$fetcher = new CrlFetcher();
$fetcher->cacheDir('/tmp/crl-cache');
$fetcher->cacheTtl(86400); // 24 hours
$crl = $fetcher->fetchForCertificate('/certs/signing.pem');
echo $crl->issuerDN();
echo $crl->revokedCount();
$crl->isRevoked('01:AB:CD:EF'); // bool
$derBytes = $crl->toDer();Construção da Cadeia de Certificados
O LtvManager segue a extensão AIA caIssuers para descobrir intermediários automaticamente. Se o HTTP de saída for restrito, forneça a cadeia manualmente via CertificateInfo::chain().
$ltv = new LtvManager($pdf);
$ltv->buildChain(signerCertificate: '/certs/signing.pem');
$chain = $ltv->chain(); // array of DER-encoded certificatesLoop de Arquivamento (B-LTA)
O B-LTA adiciona um timestamp de documento após a incorporação do DSS. Re-timestampe antes do certificado TSA expirar para manter a validade indefinidamente:
Sign (B-B) -> TSA timestamp (B-T) -> DSS (B-LT) -> Document timestamp (B-LTA)
-> [re-timestamp before expiry]$ltv = LtvManager::load('/archive/contract-2026.pdf');
$ltv->retimestamp(new TsaClient('https://tsa.example.com/timestamp'));
$ltv->save('/archive/contract-2026.pdf');Tratamento de Erros
As operações LTV lançam exceções tipadas: OcspException (respondedor inacessível), CrlException (download falhou) ou ChainBuildException (cadeia incompleta). Todas estão sob o namespace Yeeefang\TcpdfNext\Pro\Security\Ltv.
Próximos Passos
- Assinaturas Digitais PAdES -- Criação de assinaturas em todos os níveis PAdES.
- PDF/A-4 Archival -- Combine LTV com conformidade de arquivamento.
- Integração HSM -- Assinatura baseada em hardware com suporte LTV.