Ga naar inhoud
getnextpdf.com

Enterprise editie

Trusted lists — Diepe referentie

Deze pagina is de diepgaande referentie voor het trusted-list-oppervlak in NextPDF Enterprise. Het oppervlak bestaat uit de twaalf publieke klassen van de NextPDF\Enterprise\Security\Tsl-namespace. NextPDF\Enterprise\Security\Tsl\TslPolicyEnforcer is het georkestreerde toegangspunt: het geeft alleen een TslDocument terug wanneer de HTTP-fetch, XMLDSig-verificatie, structurele parse en de nextUpdate-verlopenpoort allemaal slagen. TslTrustAnchorProvider::buildBundle() leidt vervolgens een trust-anchor-bundel af uit actieve CA/QC-services, waarbij de versheid opnieuw wordt bevestigd op een door de aanroeper opgegeven tijdstip voordat er een anchor wordt geëxtraheerd. Elke fout werpt een getypeerde exception op; geen enkele fase degradeert stilzwijgend. De pipeline ondersteunt het verifiëren van trusted lists van EU-lidstaten en van LOTL (List of Trusted Lists)-afkomstige trust anchors wanneer die door de aanroeper worden aangeleverd; automatische LOTL-ontdekking, polling en pivot-verwerking vallen buiten de scope.

Deze mogelijkheid wordt geleverd in NextPDF Enterprise (nextpdf/enterprise) en wordt geactiveerd met een licentie-envelop op Enterprise-niveau. Een deployment zonder die entitlement laadt de klassen van deze mogelijkheid niet. Vergelijk edities en verkrijg een licentie.

SymboolParametersStandaardgedragRetourneertWerpt of faalt metOpmerkingen
TslPolicyEnforcerTslFetcher $fetcher, TslSignatureVerifier $verifier, TslXmlParser $parserCombineert fetch, signature-verify, parse en verlopenpoort tot één toegangspuntPropageert de onderstaande pipeline-exceptiesfinal; fail-closed door constructie
TslPolicyEnforcer::fetchAndVerifystring $urlHaalt één TSL op en draait dan verifyXml() op de bytesTslDocumentTslFetchException, NetworkPolicyViolation, TslSignatureException, TslParseExceptionRetourneert alleen wanneer alle vier de fasen slagen
TslPolicyEnforcer::verifyXmlstring $xmlVerifieert de handtekening, parseert en weigert een verlopen lijstTslDocumentTslSignatureException, TslParseExceptionVerlopenheid wordt geëvalueerd tegen de huidige systeemtijd
TslFetcherClientInterface $httpClient, RequestFactoryInterface $requestFactory, ?CacheInterface $cache = null, int $defaultTtlSeconds = 3600, int $maxBytes = 16_777_216, NetworkPolicy $networkPolicy = NetworkPolicy::ONLINEHTTPS-only TSL/LOTL-ophalen met ETag-gebaseerde cachingfinal; SSRF-bescherming blokkeert private, loopback-, link-local- en metadata-hosts met DNS-rebinding-mitigatie
TslFetcher::fetchstring $urlGET met If-None-Match-hervalidatie; cachet de body plus ETag onder de geconfigureerde TTLstring (raw XML-bytes)TslFetchException, NetworkPolicyViolationLeest hoogstens $maxBytes bytes; onder STRICT_OFFLINE wordt alleen een gecachte body geserveerd
TslSignatureVerifierarray $trustAnchorsPem, int $clockTolerance = 0XMLDSig-verifier vastgezet op geconfigureerde trust anchorsInvalidArgumentException wanneer de anchorlijst leeg isfinal; allowlists in ALLOWED_SIG_ALG en ALLOWED_DIGEST_ALG
TslSignatureVerifier::verifystring $xmlVerifieert de enveloped XMLDSig-handtekening fail-closedstring (PEM van ondertekenaarcertificaat)TslSignatureException met een machineleesbare reason codeKeyInfo-certificaten worden nooit op zichzelf vertrouwd; de ondertekenaar moet ketenen naar een geconfigureerd anchor
TslXmlParser::parsestring $xmlStructurele parse naar een TslDocument; handtekening-agnostischTslDocumentTslParseExceptionWeigert elke DOCTYPE fail-closed vóór het parsen; laadt met LIBXML_NONET; aanroepers moeten verifiëren voordat ze het resultaat vertrouwen
TslTrustAnchorProvider::buildBundleTslDocument $tsl, DateTimeImmutable $nowBevestigt eerst de versheid, verzamelt dan de certificaten van actieve CA/QC-servicesEnterpriseCaTrustAnchorBundleTslParseExceptionDe versheidspoort gaat vooraf aan elke anchorextractie; een lege resultaatverzameling werpt
TslDocumentAcht gepromote readonly properties (zie constructor-fence)Immutable geparseerde TSL-value-objectfinal readonly; source-geannoteerd @api
TslDocument::isStaleDateTimeImmutable $nowVergelijkt nextUpdate met $now na een fail-closed UTC-parseboolTslParseExceptionVereist een expliciete Z- of numerieke-offset-aanduiding
TslDocument::assertFreshDateTimeImmutable $nowWerpt wanneer de lijst verlopen is of nextUpdate niet parseerbaar isvoidTslParseExceptionDe versheidspoort op de consumentgrens
TslDocument::servicesOfTypestring $serviceTypeIdentifierFiltert services op ETSI service-type-URIlist<TspService>Werpt niet
TslDocument::activeServicesRetourneert alleen services in granted-statuslist<TspService>Werpt nietGranted betekent TspService::STATUS_GRANTED
TspServiceAcht gepromote readonly propertiesEén trust-service-vermelding binnen een TSLfinal readonly; constanten voor status en service-type-URI’s
TspService::isGrantedStatusgelijkheid tegen de granted-URIboolWerpt niet
TspService::isQualifiedCaTypegelijkheid tegen de CA/QC-URIboolWerpt niet
TspServiceQualifierstring $qualifierUri, string $criteriaListAssert = 'all', array $policyOidConditions = [], array $keyUsageConditions = []Eén ETSI service-qualifier met optionele criteriafinal readonly; constanten FOR_ESIG, FOR_ESEAL, FOR_WSA, QSCD_STATEMENT, NO_QSCD
EnterpriseCaTrustAnchorBundlearray $anchorsPem, string $bundleVersion, string $bundleSha256Pinned-anchor-bundel; valideert bij constructie de opgegeven digest tegen de opgegeven anchorsInvalidArgumentExceptionVerkrijg via buildBundle(); niet handmatig construeren; implementeert TrustAnchorStoreInterface
EnterpriseCaTrustAnchorBundle::containsFingerprintstring $anchorDerSha256HexAnchor-lidmaatschap op hex SHA-256 over de DER-bodyboolWerpt niet
EnterpriseCaTrustAnchorBundle::computeBundleSha256array $anchorsPemCanonieke SHA-256 over newline-genormaliseerde PEM-concatenatiestringWerpt nietstatic
TslFetchExceptionSignaleert een mislukt TSL-ophalenfinal; breidt RuntimeException uit
TslParseExceptionSignaleert een structurele of versheidsfoutfinal; breidt RuntimeException uit
TslSignatureExceptionstring $reason, string $messageSignaleert XMLDSig-verificatiefout met een reason codefinal; publieke readonly $reason (zie reason codes hieronder)

TslPolicyEnforcer

public function fetchAndVerify(string $url): TslDocument
public function verifyXml(string $xml): TslDocument

TslFetcher

public function __construct(
private readonly ClientInterface $httpClient,
private readonly RequestFactoryInterface $requestFactory,
private readonly ?CacheInterface $cache = null,
private readonly int $defaultTtlSeconds = 3600,
private readonly int $maxBytes = 16_777_216,
private readonly NetworkPolicy $networkPolicy = NetworkPolicy::ONLINE,
) {}
public function fetch(string $url): string

TslSignatureVerifier

public function __construct(private readonly array $trustAnchorsPem, private readonly int $clockTolerance = 0)
public function verify(string $xml): string

TslXmlParser

public function parse(string $xml): TslDocument

TslTrustAnchorProvider

public function buildBundle(TslDocument $tsl, DateTimeImmutable $now): EnterpriseCaTrustAnchorBundle

TslDocument

public function __construct(
public string $schemeTerritory,
public string $schemeOperatorName,
public string $tslType,
public int $sequenceNumber,
public string $issueDateTime,
public string $nextUpdate,
public array $tspServices,
public string $rawXmlSha256,
) {}
public function isStale(DateTimeImmutable $now): bool
public function assertFresh(DateTimeImmutable $now): void
public function servicesOfType(string $serviceTypeIdentifier): array
public function activeServices(): array

TspService

public function __construct(public string $tspName, public string $serviceName, public string $serviceTypeIdentifier, public string $serviceStatus, public string $statusStartingTime, public string $serviceCertificatePem, public array $qualifiers, public array $additionalServiceInformation) {}
public function isGranted(): bool
public function isQualifiedCa(): bool

TspServiceQualifier

public function __construct(public string $qualifierUri, public string $criteriaListAssert = 'all', public array $policyOidConditions = [], public array $keyUsageConditions = []) {}

EnterpriseCaTrustAnchorBundle

public function __construct(public array $anchorsPem, public string $bundleVersion, public string $bundleSha256)
public function containsFingerprint(string $anchorDerSha256Hex): bool
public static function computeBundleSha256(array $anchorsPem): string

TslSignatureException

public function __construct(public readonly string $reason, string $message)

TslSignatureException reason codes: missing_signature, untrusted_signer, invalid_signature, digest_mismatch, unsupported_algorithm, unsupported_transform, expired_anchor.

  • De pipeline-volgorde ligt vast: fetch, XMLDSig-verificatie, structurele parse, verlopenpoort. TslPolicyEnforcer geeft alleen een TslDocument terug wanneer alle vier slagen. Een trusted list wordt ondertekend door haar scheme operator zodat vertrouwende partijen de authenticiteit en integriteit kunnen controleren — ETSI TS 119 612 §5.7.1.
  • TslXmlParser is handtekening-agnostisch van opzet. Aanroepers moeten de handtekening verifiëren voordat ze enig geparseerd veld vertrouwen. TslPolicyEnforcer::verifyXml() handhaaft die volgorde.
  • De versheidsinvariant wordt op elke consumentgrens gehandhaafd. Een lijst waarvan nextUpdate verstreken is, is verlopen en wordt geweigerd — ETSI TS 119 612 §5.3.15. verifyXml() poort tegen de huidige systeemtijd; TslDocument::assertFresh() en buildBundle() poorten tegen een door de aanroeper opgegeven tijdstip.
  • De versheidsparse is fail-closed. Datum-tijdvelden zijn ISO 8601 UTC-waarden met een expliciete aanduiding — ETSI TS 119 612 §5.1.3. Een nextUpdate zonder expliciete Z of numerieke offset werpt TslParseException; de waarde wordt nooit heringterpreteerd in de lokale tijdzone van de server.
  • buildBundle() roept assertFresh($now) aan voordat er een anchor wordt geëxtraheerd, en laat dan alleen services toe die zowel granted als CA/QC zijn. Granted en withdrawn zijn de status-URI’s van gekwalificeerde services — ETSI TS 119 612 §5.5.4. CA/QC is de service-type-URI van de gekwalificeerde CA — ETSI TS 119 612 §5.5.1.1.
  • De bundelversie wordt afgeleid uit het scheme-territorium en het TSL-volgnummer. Het volgnummer is monotoon over releases heen — ETSI TS 119 612 §5.3.2. De bundeldigest is een canonieke SHA-256 over de anchor-PEM’s, en containsFingerprint() beantwoordt lidmaatschap via DER SHA-256.
  • De verifier vertrouwt alleen geconfigureerde anchors. Certificaten die in KeyInfo worden gevonden, dienen als de ondertekenaar-leaf en kandidaat-intermediates; de keten moet binnen diepte 8 een geconfigureerd anchor bereiken, elke schakel moet temporeel geldig zijn, en een uitgevend certificaat moet basicConstraints cA=TRUE dragen (plus keyCertSign wanneer keyUsage aanwezig is).
  • Het verificatieprofiel is een allowlist: RSA of ECDSA met SHA-256, SHA-384 of SHA-512; digest-methoden SHA-256, SHA-384 of SHA-512; alleen exclusieve canonicalisatie; en precies het paar enveloped-signature plus exclusieve-C14N-transform op de lijst-dekkende ds:Reference. Alles anders faalt met unsupported_algorithm of unsupported_transform.
  • TslFetcher weigert niet-HTTPS-URL’s en past een SSRF-bescherming toe vóór elke egress. Onder NetworkPolicy::STRICT_OFFLINE serveert het een eerder gecachte body of werpt het NetworkPolicyViolation; er wordt nooit een uitgaand verzoek verzonden.
  • Verlopen lijst. TslParseException uit verifyXml(), assertFresh() of buildBundle() betekent dat de trust-bron onbruikbaar is. Behandel het als een operationele verversingsfout, niet als een handtekeningverdict.
  • Niet-canonieke nextUpdate. Een waarde zonder expliciete Z of numerieke offset werpt in plaats van soepel te parsen. ETSI TS 119 612 §5.1.3 verplicht de UTC-Z-vorm; de poort accepteert ook een expliciete numerieke offset en verwerpt al het overige.
  • Time-of-use-drift. verifyXml() poort op verificatietijd; een document dat in het geheugen voorbij nextUpdate wordt vastgehouden, faalt alsnog op de latere buildBundle($tsl, $now)-poort.
  • Lege anchor-configuratie. TslSignatureVerifier weigert constructie met een lege anchorlijst (InvalidArgumentException).
  • Geen bruikbare services. Een verse lijst zonder granted CA/QC-services werpt TslParseException uit buildBundle(); een lege bundel wordt nooit geproduceerd.
  • Offline-houding. STRICT_OFFLINE zonder gecachte body werpt NetworkPolicyViolation. De cache-lookup gaat vooraf aan de policy-controle, zodat een gecachte lijst air-gapped-validatie werkend houdt.
  • Te grote of lege respons. fetch() leest hoogstens $maxBytes bytes (standaard 16 MiB); een afgekapte lijst faalt dan stroomafwaarts bij de digest-verificatie. Een lege body werpt TslFetchException.
  • DOCTYPE in de XML. Elke DOCTYPE wordt geweigerd voordat libxml een entiteitentabel opbouwt, en opnieuw na het laden. Dit sluit de invoerklassen XXE en entity-expansion (billion-laughs) af.
  • Meerdere handtekeningen. Alleen de geverifieerde enveloped ds:Signature wordt verwijderd vóór de digest-berekening; broer-handtekeningen en counter-signatures blijven behouden. Aanvullende XAdES-references zijn toegestaan, maar precies één ds:Reference moet de document-root dekken.
  • Verlopen ketenmateriaal. Een verlopen of nog-niet-geldige ondertekenaar, intermediate of anchor faalt met reason expired_anchor. clockTolerance verbreedt het acceptatievenster symmetrisch en heeft standaard 0.

De allowlist van de verifier ligt vast op RSA en ECDSA met de SHA-2-familie; SHA-1 en MD5 zijn structureel uitgesloten. De handtekening-rekenkunde draait in gebundelde software-cryptografie (phpseclib). NextPDF doet geen FIPS 140-3-validatieclaim voor die rekenkunde. Het Enterprise FIPS 140-3-crypto-policy-profiel is gedocumenteerd bij de security-module; het beperkt de algoritmeselectie en verandert niets aan trusted-list-structuren of aan het fail-closed-gedrag van deze module.

ClaimStandaardClausule
Een trusted list waarvan de Next update verstreken is, wordt als verlopen verworpen.ETSI TS 119 612§5.3.15
Datum-tijdvelden zijn ISO 8601-strings in UTC met de Z-aanduiding.ETSI TS 119 612§5.1.3
De scheme operator ondertekent de trusted list voor authenticiteit en integriteit.ETSI TS 119 612§5.7.1
Gekwalificeerde-service-status is de granted- of withdrawn-status-URI.ETSI TS 119 612§5.5.4
Een gekwalificeerde CA wordt geïdentificeerd door de Svctype/CA/QC-service-type-URI.ETSI TS 119 612§5.5.1.1
Het TSL-volgnummer begint bij 1 en verhoogt bij elke release.ETSI TS 119 612§5.3.2

Alle clausules zijn geparafraseerd; NextPDF reproduceert geen normatieve tekst. NextPDF doet geen ETSI TS 119 612-conformiteitsclaim en geen eIDAS-certificeringsclaim. Het consumeren van een trusted list maakt een handtekening, een certificaat of een NextPDF-output niet “gekwalificeerd”; kwalificatie behoort toe aan de trust service provider onder toezicht van de lidstaat, en rechtsgevolg valt buiten deze module. De XMLDSig-verwerkingsmodel-beperkingen (enveloped-signature-transform, exclusieve canonicalisatie, root-dekkende reference) zijn gedocumenteerd vanuit het verificatieprofiel van het product; de W3C XML Signature-specificatie valt buiten de geciteerde bewijsverzameling. Deze module beslist alleen of een lijst aanvaardbaar is als trust-invoer; certificaat-pad-validatie tegen de resulterende anchors behoort tot de certificaat-validatielaag.

  • Afhankelijkheden zijn PSR-interfaces: een PSR-18 client, een PSR-17 request factory en een optionele PSR-16 cache. Injecteer in-memory doubles in tests; geen enkele fase vereist live netwerktoegang behalve een koude fetch().
  • Zet het top-anchor out of band vast. Voor lidstaatlijsten autoriseert het LOTL-anchor de lijst-ondertekenaars; de verifier bootstrapt vertrouwen nooit vanuit KeyInfo-inhoud.
  • Achtergrond-polling, pivot-LOTL-verwerking en mutual-TLS- of proxy-authenticatie vallen in deze versie buiten de scope van de fetcher. Plan verversing extern en fetch opnieuw vóór elke nextUpdate.
  • Geef het validatietijdstip door aan buildBundle(), niet het constructietijdstip. Herbouw de bundel na elke verversing; cache een bundel nooit voorbij de nextUpdate van de bronlijst.
  • bundleVersion heeft de waarneembare vorm tsl-<territory>-seq<sequenceNumber>; rawXmlSha256 op TslDocument ondersteunt bewijsrecords en replay-detectie.
  • Misvormde service-vermeldingen parsen met defensieve placeholderwaarden; een misvormde digitale identiteit die de bundelconstructie bereikt, faalt fail-closed met InvalidArgumentException.
  • De klassen dragen source-annotaties met package @since 1.10.0 (TslFetchException: 3.2.0). TslDocument, TspService en TspServiceQualifier zijn source-geannoteerd @api.

Deze pagina documenteert alleen extern waarneembaar gedrag en het ondersteunde publieke API-oppervlak. Interne namespace-paden, helperklassen, mechanismetabellen, runbook-bestandsnamen en ticket-prefixen vallen buiten de scope.