Enterprise edizione
Trusted list — Riferimento approfondito
In sintesi
Sezione intitolata “In sintesi”Questa pagina è il riferimento approfondito della superficie trusted-list in NextPDF Enterprise. La superficie è costituita dalle dodici classi pubbliche del namespace NextPDF\Enterprise\Security\Tsl. NextPDF\Enterprise\Security\Tsl\TslPolicyEnforcer è il punto d’ingresso orchestrato: restituisce un TslDocument solo quando fetch HTTP, verifica XMLDSig, parsing strutturale e il gate di obsolescenza su nextUpdate superano tutti la verifica. TslTrustAnchorProvider::buildBundle() deriva quindi un bundle di trust anchor dai servizi CA/QC attivi, riaffermando la freschezza a un istante fornito dal chiamante prima che venga estratto qualsiasi anchor. Ogni fallimento solleva un’eccezione tipizzata; nessuno stadio degrada silenziosamente. La pipeline supporta la verifica delle trusted list degli Stati membri dell’UE e dei trust anchor provenienti da LOTL (List of Trusted Lists) quando forniti dal chiamante; la scoperta automatica del LOTL, il polling e l’elaborazione dei pivot sono fuori ambito.
Disponibilità e licenza
Sezione intitolata “Disponibilità e licenza”Questa capacità è inclusa in NextPDF Enterprise (nextpdf/enterprise) e si attiva con un envelope di licenza di tier Enterprise. Un deployment privo di tale entitlement non carica le classi della capacità. Confronta le edizioni e ottieni una licenza.
Superficie API pubblica
Sezione intitolata “Superficie API pubblica”| Simbolo | Parametri | Comportamento predefinito | Restituisce | Solleva o fallisce con | Note |
|---|---|---|---|---|---|
TslPolicyEnforcer | TslFetcher $fetcher, TslSignatureVerifier $verifier, TslXmlParser $parser | Combina fetch, verifica firma, parsing e gate di obsolescenza in un unico punto d’ingresso | — | Propaga le eccezioni della pipeline seguenti | final; fail-closed per costruzione |
TslPolicyEnforcer::fetchAndVerify | string $url | Effettua il fetch di una TSL, quindi esegue verifyXml() sui byte | TslDocument | TslFetchException, NetworkPolicyViolation, TslSignatureException, TslParseException | Restituisce solo quando tutti e quattro gli stadi superano la verifica |
TslPolicyEnforcer::verifyXml | string $xml | Verifica la firma, esegue il parsing e rifiuta una lista obsoleta | TslDocument | TslSignatureException, TslParseException | L’obsolescenza è valutata rispetto all’ora di sistema corrente |
TslFetcher | ClientInterface $httpClient, RequestFactoryInterface $requestFactory, ?CacheInterface $cache = null, int $defaultTtlSeconds = 3600, int $maxBytes = 16_777_216, NetworkPolicy $networkPolicy = NetworkPolicy::ONLINE | Recupero TSL/LOTL solo su HTTPS con caching basato su ETag | — | — | final; la guardia SSRF blocca host privati, loopback, link-local e di metadati con mitigazione del DNS rebinding |
TslFetcher::fetch | string $url | GET con rivalidazione If-None-Match; mette in cache il body più l’ETag secondo il TTL configurato | string (byte XML grezzi) | TslFetchException, NetworkPolicyViolation | Legge al massimo $maxBytes byte; sotto STRICT_OFFLINE viene servito solo un body in cache |
TslSignatureVerifier | array $trustAnchorsPem, int $clockTolerance = 0 | Verificatore XMLDSig fissato ai trust anchor configurati | — | InvalidArgumentException quando la lista di anchor è vuota | final; allowlist in ALLOWED_SIG_ALG e ALLOWED_DIGEST_ALG |
TslSignatureVerifier::verify | string $xml | Verifica la firma XMLDSig enveloped in modalità fail-closed | string (PEM del certificato firmatario) | TslSignatureException con un codice di motivo leggibile dalla macchina | I certificati in KeyInfo non sono mai considerati affidabili da soli; il firmatario deve concatenarsi a un anchor configurato |
TslXmlParser::parse | string $xml | Parsing strutturale in un TslDocument; agnostico rispetto alla firma | TslDocument | TslParseException | Rifiuta qualsiasi DOCTYPE in modalità fail-closed prima del parsing; carica con LIBXML_NONET; i chiamanti devono verificare prima di considerare affidabile il risultato |
TslTrustAnchorProvider::buildBundle | TslDocument $tsl, DateTimeImmutable $now | Afferma prima la freschezza, quindi raccoglie i certificati dei servizi CA/QC attivi | EnterpriseCaTrustAnchorBundle | TslParseException | Il gate di freschezza precede qualsiasi estrazione di anchor; un insieme di risultati vuoto solleva un’eccezione |
TslDocument | Otto proprietà readonly promosse (vedi il fence del costruttore) | Value object immutabile della TSL parsata | — | — | final readonly; @api annotato nel sorgente |
TslDocument::isStale | DateTimeImmutable $now | Confronta nextUpdate con $now dopo un parse UTC fail-closed | bool | TslParseException | Richiede un designatore Z esplicito o un offset numerico |
TslDocument::assertFresh | DateTimeImmutable $now | Solleva un’eccezione quando la lista è obsoleta o nextUpdate non è parsabile | void | TslParseException | Il gate di freschezza al confine del consumatore |
TslDocument::servicesOfType | string $serviceTypeIdentifier | Filtra i servizi per URI di service-type ETSI | list<TspService> | Non solleva eccezioni | — |
TslDocument::activeServices | — | Restituisce solo i servizi in stato granted | list<TspService> | Non solleva eccezioni | Granted significa TspService::STATUS_GRANTED |
TspService | Otto proprietà readonly promosse | Una voce di trust-service all’interno di una TSL | — | — | final readonly; costanti per gli URI di stato e di service-type |
TspService::isGranted | — | Uguaglianza di stato rispetto all’URI granted | bool | Non solleva eccezioni | — |
TspService::isQualifiedCa | — | Uguaglianza di tipo rispetto all’URI CA/QC | bool | Non solleva eccezioni | — |
TspServiceQualifier | string $qualifierUri, string $criteriaListAssert = 'all', array $policyOidConditions = [], array $keyUsageConditions = [] | Un qualificatore di servizio ETSI con criteri opzionali | — | — | final readonly; costanti FOR_ESIG, FOR_ESEAL, FOR_WSA, QSCD_STATEMENT, NO_QSCD |
EnterpriseCaTrustAnchorBundle | array $anchorsPem, string $bundleVersion, string $bundleSha256 | Bundle di anchor fissati; convalida il digest fornito rispetto agli anchor forniti in fase di costruzione | — | InvalidArgumentException | Ottenuto da buildBundle(); non costruire a mano; implementa TrustAnchorStoreInterface |
EnterpriseCaTrustAnchorBundle::containsFingerprint | string $anchorDerSha256Hex | Appartenenza di un anchor tramite SHA-256 esadecimale sul body DER | bool | Non solleva eccezioni | — |
EnterpriseCaTrustAnchorBundle::computeBundleSha256 | array $anchorsPem | SHA-256 canonico sulla concatenazione PEM con newline normalizzate | string | Non solleva eccezioni | static |
TslFetchException | — | Segnala un recupero TSL fallito | — | — | final; estende RuntimeException |
TslParseException | — | Segnala un fallimento strutturale o di freschezza | — | — | final; estende RuntimeException |
TslSignatureException | string $reason, string $message | Segnala un fallimento della verifica XMLDSig con un codice di motivo | — | — | final; $reason pubblico readonly (vedi i codici di motivo sotto) |
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)Codici di motivo di TslSignatureException: missing_signature, untrusted_signer, invalid_signature, digest_mismatch, unsupported_algorithm, unsupported_transform, expired_anchor.
Contratto di comportamento
Sezione intitolata “Contratto di comportamento”- L’ordine della pipeline è fisso: fetch, verifica XMLDSig, parsing strutturale, gate di obsolescenza.
TslPolicyEnforcerrestituisce unTslDocumentsolo quando tutti e quattro riescono. Una trusted list è firmata dal suo scheme operator così che le relying party possano verificarne autenticità e integrità — ETSI TS 119 612 §5.7.1. TslXmlParserè agnostico rispetto alla firma per progettazione. I chiamanti devono verificare la firma prima di considerare affidabile qualsiasi campo parsato.TslPolicyEnforcer::verifyXml()impone tale ordinamento.- L’invariante di freschezza è imposta a ogni confine del consumatore. Una lista il cui
nextUpdateè trascorso è scaduta e viene rifiutata — ETSI TS 119 612 §5.3.15.verifyXml()applica il gate rispetto all’ora di sistema corrente;TslDocument::assertFresh()ebuildBundle()applicano il gate rispetto a un istante fornito dal chiamante. - Il parse di freschezza è fail-closed. I campi data-ora sono valori ISO 8601 in UTC con un designatore esplicito — ETSI TS 119 612 §5.1.3. Un
nextUpdateprivo di unZesplicito o di un offset numerico sollevaTslParseException; il valore non viene mai reinterpretato nel fuso orario locale del server. buildBundle()chiamaassertFresh($now)prima di estrarre qualsiasi anchor, quindi ammette solo i servizi che sono sia granted sia CA/QC. Granted e withdrawn sono gli URI di stato dei servizi qualificati — ETSI TS 119 612 §5.5.4. CA/QC è l’URI di service-type della CA qualificata — ETSI TS 119 612 §5.5.1.1.- La versione del bundle è derivata dal territorio dello schema e dal numero di sequenza della TSL. Il numero di sequenza è monotòno tra le release — ETSI TS 119 612 §5.3.2. Il digest del bundle è uno SHA-256 canonico sui PEM degli anchor, e
containsFingerprint()risponde sull’appartenenza tramite SHA-256 del DER. - Il verificatore considera affidabili solo gli anchor configurati. I certificati trovati in
KeyInfofungono da leaf firmatario e da intermedi candidati; la catena deve raggiungere un anchor configurato entro una profondità di 8, ogni collegamento deve essere temporalmente valido e un certificato emittente deve recarebasicConstraintscA=TRUE(piùkeyCertSignquandokeyUsageè presente). - Il profilo di verifica è un allowlist: RSA o ECDSA con SHA-256, SHA-384 o SHA-512; metodi di digest SHA-256, SHA-384 o SHA-512; solo canonicalizzazione esclusiva; ed esattamente la coppia di transform enveloped-signature più C14N esclusiva sul
ds:Referenceche copre la lista. Qualsiasi altra cosa fallisce conunsupported_algorithmounsupported_transform. TslFetcherrifiuta gli URL non HTTPS e applica una guardia SSRF prima di qualsiasi egress. SottoNetworkPolicy::STRICT_OFFLINEserve un body precedentemente messo in cache oppure sollevaNetworkPolicyViolation; nessuna richiesta in uscita viene mai inviata.
Casi limite e modalità di fallimento
Sezione intitolata “Casi limite e modalità di fallimento”- Lista obsoleta. Una
TslParseExceptiondaverifyXml(),assertFresh()obuildBundle()significa che la fonte di trust è inutilizzabile. Trattala come un fallimento operativo di refresh, non come un verdetto sulla firma. nextUpdatenon canonico. Un valore privo di unZesplicito o di un offset numerico solleva un’eccezione invece di essere parsato in modo permissivo. ETSI TS 119 612 §5.1.3 impone la forma UTCZ; il gate accetta anche un offset numerico esplicito e rifiuta tutto il resto.- Deriva del momento d’uso.
verifyXml()applica il gate al momento della verifica; un documento mantenuto in memoria oltrenextUpdatefallisce comunque il successivo gate dibuildBundle($tsl, $now). - Configurazione di anchor vuota.
TslSignatureVerifierrifiuta la costruzione con una lista di anchor vuota (InvalidArgumentException). - Nessun servizio utilizzabile. Una lista fresca senza servizi CA/QC granted solleva una
TslParseExceptiondabuildBundle(); un bundle vuoto non viene mai prodotto. - Postura offline.
STRICT_OFFLINEsenza un body in cache sollevaNetworkPolicyViolation. La ricerca in cache precede il controllo della policy, così una lista in cache mantiene funzionante la validazione air-gapped. - Risposta sovradimensionata o vuota.
fetch()legge al massimo$maxBytesbyte (predefinito 16 MiB); una lista troncata fallisce poi la verifica del digest a valle. Un body vuoto sollevaTslFetchException. - DOCTYPE nell’XML. Qualsiasi DOCTYPE viene rifiutato prima che libxml costruisca una tabella di entità, e di nuovo dopo il caricamento. Questo chiude le classi di input XXE ed espansione di entità (billion-laughs).
- Firme multiple. Solo la
ds:Signatureenveloped verificata viene rimossa prima del calcolo del digest; le firme fratelli e le contro-firme sono preservate. Sono ammessi riferimenti XAdES aggiuntivi, ma esattamente unds:Referencedeve coprire la radice del documento. - Materiale di catena scaduto. Un firmatario, un intermedio o un anchor scaduto o non ancora valido fallisce con il motivo
expired_anchor.clockToleranceallarga la finestra di accettazione in modo simmetrico e vale0per impostazione predefinita.
Comportamento in modalità FIPS
Sezione intitolata “Comportamento in modalità FIPS”L’allowlist del verificatore è fissata a RSA ed ECDSA con la famiglia SHA-2; SHA-1 e MD5 sono strutturalmente esclusi. L’aritmetica di firma viene eseguita nella crittografia software inclusa (phpseclib). NextPDF non avanza alcuna rivendicazione di validazione FIPS 140-3 per tale aritmetica. Il profilo di crypto-policy FIPS 140-3 di Enterprise è documentato con il modulo di sicurezza; vincola la selezione degli algoritmi e non modifica le strutture trusted-list né il comportamento fail-closed di questo modulo.
Conformità
Sezione intitolata “Conformità”| Rivendicazione | Standard | Clausola |
|---|---|---|
| Una trusted list il cui Next update è trascorso viene scartata come scaduta. | ETSI TS 119 612 | §5.3.15 |
I campi data-ora sono stringhe ISO 8601 in UTC con il designatore Z. | ETSI TS 119 612 | §5.1.3 |
| Lo scheme operator firma la trusted list per autenticità e integrità. | ETSI TS 119 612 | §5.7.1 |
| Lo stato dei servizi qualificati è l’URI di stato granted o withdrawn. | ETSI TS 119 612 | §5.5.4 |
Una CA qualificata è identificata dall’URI di service-type Svctype/CA/QC. | ETSI TS 119 612 | §5.5.1.1 |
| Il numero di sequenza della TSL parte da 1 e si incrementa a ogni release. | ETSI TS 119 612 | §5.3.2 |
Tutte le clausole sono parafrasate; NextPDF non riproduce il testo normativo. NextPDF non avanza alcuna rivendicazione di conformità a ETSI TS 119 612 né alcuna rivendicazione di certificazione eIDAS. Consumare una trusted list non rende una firma, un certificato o un output NextPDF “qualificato”; la qualificazione appartiene al trust service provider sotto la supervisione dello Stato membro, e l’effetto legale è al di fuori di questo modulo. I vincoli del modello di elaborazione XMLDSig (transform enveloped-signature, canonicalizzazione esclusiva, riferimento che copre la radice) sono documentati a partire dal profilo di verifica del prodotto; la specifica W3C XML Signature è al di fuori dell’insieme di evidenze citate. Questo modulo decide solo se una lista sia accettabile come input di trust; la validazione del percorso di certificazione rispetto agli anchor risultanti appartiene al livello di validazione dei certificati.
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Le dipendenze sono interfacce PSR: un client PSR-18, una request factory PSR-17 e una cache PSR-16 opzionale. Inietta double in-memory nei test; nessuno stadio richiede accesso di rete reale tranne un
fetch()a freddo. - Fissa l’anchor superiore out of band. Per le liste degli Stati membri, l’anchor LOTL autorizza i firmatari delle liste; il verificatore non avvia mai la trust a partire dal contenuto di
KeyInfo. - Il polling in background, l’elaborazione del pivot-LOTL e l’autenticazione mutual-TLS o proxy sono fuori dall’ambito del fetcher in questa versione. Pianifica il refresh esternamente e riesegui il fetch prima di ogni
nextUpdate. - Passa l’istante di validazione, non l’istante di costruzione, a
buildBundle(). Ricostruisci il bundle dopo ogni refresh; non mettere mai in cache un bundle oltre ilnextUpdatedella lista sorgente. bundleVersionha la forma osservabiletsl-<territory>-seq<sequenceNumber>;rawXmlSha256suTslDocumentsupporta i record di evidenza e il rilevamento del replay.- Le voci di servizio malformate vengono parsate con valori placeholder difensivi; un’identità digitale malformata che raggiunge la costruzione del bundle fallisce in modalità fail-closed con
InvalidArgumentException. - Le classi recano annotazioni sorgente di package
@since 1.10.0(TslFetchException:3.2.0).TslDocument,TspServiceeTspServiceQualifiersono annotati@apinel sorgente.
Vedi anche
Sezione intitolata “Vedi anche”- Livelli di garanzia eIDAS — la pagina di capacità che mappa le evidenze trusted-list ai Livelli di Garanzia.
- Container ASiC — un consumatore di
TslTrustAnchorProvider::buildBundle()per il binding di trust del container. - Verifica della firma — il lato verify AdES/PAdES che consuma i trust anchor.
- Sicurezza — Riferimento approfondito — la superficie di sicurezza Enterprise combinata.
- Firma — Riferimento approfondito — il produttore a lungo termine PAdES B-LT e B-LTA.
Confine di pubblicazione
Sezione intitolata “Confine di pubblicazione”Questa pagina documenta solo il comportamento osservabile dall’esterno e la superficie API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi dei file di runbook e i prefissi dei ticket sono fuori ambito.