Skip to content

Долгосрочная валидация

Pro — Commercial License Required
Долгосрочная валидация (LTV) требует пакет Pro.

LTV гарантирует, что подписи остаются верифицируемыми после истечения срока действия сертификатов или отключения сервисов отзыва, путём встраивания всех данных валидации в PDF через Document Security Store (DSS).

Классы LTV

КлассНазначение
LtvManagerОркестрирует построение цепочки, получение OCSP/CRL, сборку DSS
DssBuilderСтроит словарь DSS с сертификатами, OCSP, CRL
OcspClientПолучает OCSP-ответы (RFC 6960)
CrlFetcherЗагружает CRL из точек распространения (RFC 5280)

LtvManager

На уровнях B-LT или B-LTA LtvManager запускается автоматически внутри DigitalSigner. Для ручного управления:

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

Конструирует словарь DSS (ISO 32000-2), содержащий /Certs, /OCSPs, /CRLs и опциональные записи /VRI для каждой подписи.

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

Запрашивает OCSP-респондеры для проверки статуса отзыва сертификата.

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

Загружает CRL из точек распространения CDP, объявленных в сертификатах, с опциональным кешированием на диске.

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();

Построение цепочки сертификатов

LtvManager следует расширению AIA caIssuers для автоматического обнаружения промежуточных сертификатов. Если исходящий HTTP ограничен, предоставьте цепочку вручную через CertificateInfo::chain().

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

Архивный цикл (B-LTA)

B-LTA добавляет метку времени документа после встраивания DSS. Повторно ставьте метку времени до истечения сертификата TSA для поддержания валидности бессрочно:

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');

Обработка ошибок

Операции LTV выбрасывают типизированные исключения: OcspException (респондер недоступен), CrlException (ошибка загрузки) или ChainBuildException (неполная цепочка). Все находятся в namespace Yeeefang\TcpdfNext\Pro\Security\Ltv.

Далее

Распространяется по лицензии LGPL-3.0-or-later.