Skip to content

Long-Term Validation

Pro — Commercial License Required
Long-Term Validation (LTV) requer o pacote Pro.

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

ClasseFinalidade
LtvManagerOrquestra construção de cadeia, busca OCSP/CRL, montagem DSS
DssBuilderConstrói o dicionário DSS com certs, OCSPs, CRLs
OcspClientBusca respostas OCSP (RFC 6960)
CrlFetcherBaixa 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:

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(); // builds and embeds the DSS dictionary

DssBuilder

Constrói o dicionário DSS (ISO 32000-2) contendo /Certs, /OCSPs, /CRLs e entradas /VRI opcionais por assinatura.

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]); // optional per-signature VRI
$dssDict = $dss->build();

OcspClient

Consulta respondedores OCSP para verificar o status de revogação de certificados.

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', // 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.

php
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().

php
$ltv = new LtvManager($pdf);
$ltv->buildChain(signerCertificate: '/certs/signing.pem');
$chain = $ltv->chain(); // array of DER-encoded certificates

Loop 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]
php
$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

Distribuído sob a licença LGPL-3.0-or-later.