Enterprise editie
Trusted lists — Diepe referentie
In een oogopslag
Sectie met titel “In een oogopslag”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.
Beschikbaarheid & licentie
Sectie met titel “Beschikbaarheid & licentie”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.
Publiek API-oppervlak
Sectie met titel “Publiek API-oppervlak”| Symbool | Parameters | Standaardgedrag | Retourneert | Werpt of faalt met | Opmerkingen |
|---|---|---|---|---|---|
TslPolicyEnforcer | TslFetcher $fetcher, TslSignatureVerifier $verifier, TslXmlParser $parser | Combineert fetch, signature-verify, parse en verlopenpoort tot één toegangspunt | — | Propageert de onderstaande pipeline-excepties | final; fail-closed door constructie |
TslPolicyEnforcer::fetchAndVerify | string $url | Haalt één TSL op en draait dan verifyXml() op de bytes | TslDocument | TslFetchException, NetworkPolicyViolation, TslSignatureException, TslParseException | Retourneert alleen wanneer alle vier de fasen slagen |
TslPolicyEnforcer::verifyXml | string $xml | Verifieert de handtekening, parseert en weigert een verlopen lijst | TslDocument | TslSignatureException, TslParseException | Verlopenheid wordt geëvalueerd tegen de huidige systeemtijd |
TslFetcher | ClientInterface $httpClient, RequestFactoryInterface $requestFactory, ?CacheInterface $cache = null, int $defaultTtlSeconds = 3600, int $maxBytes = 16_777_216, NetworkPolicy $networkPolicy = NetworkPolicy::ONLINE | HTTPS-only TSL/LOTL-ophalen met ETag-gebaseerde caching | — | — | final; SSRF-bescherming blokkeert private, loopback-, link-local- en metadata-hosts met DNS-rebinding-mitigatie |
TslFetcher::fetch | string $url | GET met If-None-Match-hervalidatie; cachet de body plus ETag onder de geconfigureerde TTL | string (raw XML-bytes) | TslFetchException, NetworkPolicyViolation | Leest hoogstens $maxBytes bytes; onder STRICT_OFFLINE wordt alleen een gecachte body geserveerd |
TslSignatureVerifier | array $trustAnchorsPem, int $clockTolerance = 0 | XMLDSig-verifier vastgezet op geconfigureerde trust anchors | — | InvalidArgumentException wanneer de anchorlijst leeg is | final; allowlists in ALLOWED_SIG_ALG en ALLOWED_DIGEST_ALG |
TslSignatureVerifier::verify | string $xml | Verifieert de enveloped XMLDSig-handtekening fail-closed | string (PEM van ondertekenaarcertificaat) | TslSignatureException met een machineleesbare reason code | KeyInfo-certificaten worden nooit op zichzelf vertrouwd; de ondertekenaar moet ketenen naar een geconfigureerd anchor |
TslXmlParser::parse | string $xml | Structurele parse naar een TslDocument; handtekening-agnostisch | TslDocument | TslParseException | Weigert elke DOCTYPE fail-closed vóór het parsen; laadt met LIBXML_NONET; aanroepers moeten verifiëren voordat ze het resultaat vertrouwen |
TslTrustAnchorProvider::buildBundle | TslDocument $tsl, DateTimeImmutable $now | Bevestigt eerst de versheid, verzamelt dan de certificaten van actieve CA/QC-services | EnterpriseCaTrustAnchorBundle | TslParseException | De versheidspoort gaat vooraf aan elke anchorextractie; een lege resultaatverzameling werpt |
TslDocument | Acht gepromote readonly properties (zie constructor-fence) | Immutable geparseerde TSL-value-object | — | — | final readonly; source-geannoteerd @api |
TslDocument::isStale | DateTimeImmutable $now | Vergelijkt nextUpdate met $now na een fail-closed UTC-parse | bool | TslParseException | Vereist een expliciete Z- of numerieke-offset-aanduiding |
TslDocument::assertFresh | DateTimeImmutable $now | Werpt wanneer de lijst verlopen is of nextUpdate niet parseerbaar is | void | TslParseException | De versheidspoort op de consumentgrens |
TslDocument::servicesOfType | string $serviceTypeIdentifier | Filtert services op ETSI service-type-URI | list<TspService> | Werpt niet | — |
TslDocument::activeServices | — | Retourneert alleen services in granted-status | list<TspService> | Werpt niet | Granted betekent TspService::STATUS_GRANTED |
TspService | Acht gepromote readonly properties | Eén trust-service-vermelding binnen een TSL | — | — | final readonly; constanten voor status en service-type-URI’s |
TspService::isGranted | — | Statusgelijkheid tegen de granted-URI | bool | Werpt niet | — |
TspService::isQualifiedCa | — | Typegelijkheid tegen de CA/QC-URI | bool | Werpt niet | — |
TspServiceQualifier | string $qualifierUri, string $criteriaListAssert = 'all', array $policyOidConditions = [], array $keyUsageConditions = [] | Eén ETSI service-qualifier met optionele criteria | — | — | final readonly; constanten FOR_ESIG, FOR_ESEAL, FOR_WSA, QSCD_STATEMENT, NO_QSCD |
EnterpriseCaTrustAnchorBundle | array $anchorsPem, string $bundleVersion, string $bundleSha256 | Pinned-anchor-bundel; valideert bij constructie de opgegeven digest tegen de opgegeven anchors | — | InvalidArgumentException | Verkrijg via buildBundle(); niet handmatig construeren; implementeert TrustAnchorStoreInterface |
EnterpriseCaTrustAnchorBundle::containsFingerprint | string $anchorDerSha256Hex | Anchor-lidmaatschap op hex SHA-256 over de DER-body | bool | Werpt niet | — |
EnterpriseCaTrustAnchorBundle::computeBundleSha256 | array $anchorsPem | Canonieke SHA-256 over newline-genormaliseerde PEM-concatenatie | string | Werpt niet | static |
TslFetchException | — | Signaleert een mislukt TSL-ophalen | — | — | final; breidt RuntimeException uit |
TslParseException | — | Signaleert een structurele of versheidsfout | — | — | final; breidt RuntimeException uit |
TslSignatureException | string $reason, string $message | Signaleert XMLDSig-verificatiefout met een reason code | — | — | final; publieke readonly $reason (zie reason codes hieronder) |
TslPolicyEnforcer
public function fetchAndVerify(string $url): TslDocumentpublic function verifyXml(string $xml): TslDocumentTslFetcher
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): stringTslSignatureVerifier
public function __construct(private readonly array $trustAnchorsPem, private readonly int $clockTolerance = 0)
public function verify(string $xml): stringTslXmlParser
public function parse(string $xml): TslDocumentTslTrustAnchorProvider
public function buildBundle(TslDocument $tsl, DateTimeImmutable $now): EnterpriseCaTrustAnchorBundleTslDocument
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): boolpublic function assertFresh(DateTimeImmutable $now): voidpublic function servicesOfType(string $serviceTypeIdentifier): arraypublic function activeServices(): arrayTspService
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(): boolpublic function isQualifiedCa(): boolTspServiceQualifier
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): boolpublic static function computeBundleSha256(array $anchorsPem): stringTslSignatureException
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.
Gedragscontract
Sectie met titel “Gedragscontract”- De pipeline-volgorde ligt vast: fetch, XMLDSig-verificatie, structurele parse, verlopenpoort.
TslPolicyEnforcergeeft alleen eenTslDocumentterug 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. TslXmlParseris 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
nextUpdateverstreken is, is verlopen en wordt geweigerd — ETSI TS 119 612 §5.3.15.verifyXml()poort tegen de huidige systeemtijd;TslDocument::assertFresh()enbuildBundle()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
nextUpdatezonder explicieteZof numerieke offset werptTslParseException; de waarde wordt nooit heringterpreteerd in de lokale tijdzone van de server. buildBundle()roeptassertFresh($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
KeyInfoworden 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 moetbasicConstraintscA=TRUEdragen (pluskeyCertSignwanneerkeyUsageaanwezig 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 metunsupported_algorithmofunsupported_transform. TslFetcherweigert niet-HTTPS-URL’s en past een SSRF-bescherming toe vóór elke egress. OnderNetworkPolicy::STRICT_OFFLINEserveert het een eerder gecachte body of werpt hetNetworkPolicyViolation; er wordt nooit een uitgaand verzoek verzonden.
Randgevallen & faalmodi
Sectie met titel “Randgevallen & faalmodi”- Verlopen lijst.
TslParseExceptionuitverifyXml(),assertFresh()ofbuildBundle()betekent dat de trust-bron onbruikbaar is. Behandel het als een operationele verversingsfout, niet als een handtekeningverdict. - Niet-canonieke
nextUpdate. Een waarde zonder explicieteZof 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 voorbijnextUpdatewordt vastgehouden, faalt alsnog op de laterebuildBundle($tsl, $now)-poort. - Lege anchor-configuratie.
TslSignatureVerifierweigert constructie met een lege anchorlijst (InvalidArgumentException). - Geen bruikbare services. Een verse lijst zonder granted CA/QC-services werpt
TslParseExceptionuitbuildBundle(); een lege bundel wordt nooit geproduceerd. - Offline-houding.
STRICT_OFFLINEzonder gecachte body werptNetworkPolicyViolation. 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$maxBytesbytes (standaard 16 MiB); een afgekapte lijst faalt dan stroomafwaarts bij de digest-verificatie. Een lege body werptTslFetchException. - 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:Signaturewordt verwijderd vóór de digest-berekening; broer-handtekeningen en counter-signatures blijven behouden. Aanvullende XAdES-references zijn toegestaan, maar precies éénds:Referencemoet de document-root dekken. - Verlopen ketenmateriaal. Een verlopen of nog-niet-geldige ondertekenaar, intermediate of anchor faalt met reason
expired_anchor.clockToleranceverbreedt het acceptatievenster symmetrisch en heeft standaard0.
FIPS-mode-gedrag
Sectie met titel “FIPS-mode-gedrag”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.
Conformiteit
Sectie met titel “Conformiteit”| Claim | Standaard | Clausule |
|---|---|---|
| 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.
Ontwikkelingsnotities
Sectie met titel “Ontwikkelingsnotities”- 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 denextUpdatevan de bronlijst. bundleVersionheeft de waarneembare vormtsl-<territory>-seq<sequenceNumber>;rawXmlSha256opTslDocumentondersteunt 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,TspServiceenTspServiceQualifierzijn source-geannoteerd@api.
Zie ook
Sectie met titel “Zie ook”- eIDAS-zekerheidsniveaus — de mogelijkheidspagina die trusted-list-bewijs koppelt aan Levels of Assurance.
- ASiC-containers — een consument van
TslTrustAnchorProvider::buildBundle()voor container-trust-binding. - Handtekeningverificatie — de AdES/PAdES-verificatiezijde die trust anchors consumeert.
- Security — diepgaande referentie — het gecombineerde Enterprise-security-oppervlak.
- Signature — diepgaande referentie — de PAdES B-LT- en B-LTA-langetermijnproducent.
Publicatiegrens
Sectie met titel “Publicatiegrens”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.