Enterprise edizione
Verifica delle firme — Riferimento approfondito
In sintesi
Sezione intitolata “In sintesi”Questa pagina è il riferimento approfondito della superficie di verifica AdES in NextPDF Enterprise. Il punto di ingresso è NextPDF\Enterprise\Security\Validation\AdESValidationEngine. Implementa i flussi di validazione modellati secondo ETSI di NextPDF per i controlli basic, con tempo, a lungo termine e con marca temporale di archiviazione: validazione basic, validazione con tempo, validazione con dati a lungo termine e validazione della catena di copertura DocTimeStamp di archiviazione. Gli esiti sono valori ValidationReport che trasportano casi enum MainIndication e SubIndication con valori stringa URN ETSI. Superfici di supporto documentate qui: la SPI SignatureDataExtractor e la sua implementazione CmsSignatureDataExtractor, lo scanner a livello di byte PdfSignatureDictionaryScanner, la superficie di validazione del percorso NextPDF\Enterprise\Security\Pki e BatchSignatureValidator. Per una guida a livello di flusso di lavoro, vedere Verifica delle firme: verifica crittografica AdES / PAdES.
Disponibilità e licenze
Sezione intitolata “Disponibilità e licenze”Questa capacità è inclusa in NextPDF Enterprise (nextpdf/enterprise) e si attiva con un envelope di licenza di livello Enterprise. Un deployment privo di tale titolo 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 |
|---|---|---|---|---|---|
AdESValidationEngine::__construct | 11 parametri opzionali: ?PathValidatorInterface $chainValidator, ?SignatureDataExtractor $extractor, ClockInterface $clock, ?LoggerInterface $logger, string $defaultPolicy, NetworkPolicy $networkPolicy e cinque collaboratori verifier opzionali | Tutti i valori predefiniti sono fail-closed: validatore di percorso Pki sull’orologio del motore, nessun extractor, nessuno store di fiducia TSA | Nuovo motore | Non solleva | Senza store di fiducia, la valutazione della catena TSA riporta non attendibile; ciò mappa a INDETERMINATE, mai a un esito positivo |
AdESValidationEngine::validateBasic | string $signedData, string $signature | Validazione basic: formato, digest, crypto, algoritmo debole, catena, revoca vincolata alla provenienza | ValidationReport | Non solleva; i fallimenti di estrazione e di percorso mappano a report fail-closed | Senza un extractor, solo controlli di guardia; vedere i casi limite |
AdESValidationEngine::validateWithTime | string $signedData, string $signature, DateTimeImmutable $claimedTime | Prima la validazione basic; finestra del certificato e revoca confrontate con il tempo dichiarato | ValidationReport | Non solleva | Gate rigoroso della marca temporale di firma quando l’attributo è presente; $claimedTime resta l’ancora temporale |
AdESValidationEngine::validateWithLongTermData | string $signedData, string $signature, array $dssData (certs/ocsps/crls) | Passaggio basic richiesto; gate della marca temporale di firma armato con TSA-at-genTime; gate POE, revoca DSS e archiviazione | ValidationReport | Non solleva | NetworkPolicy::STRICT_OFFLINE con dati incorporati insufficienti produce INDETERMINATE / TRY_LATER |
AdESValidationEngine::validateArchivalTimestampChain | string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null | Catena di copertura DocTimeStamp basata su evidenze sugli esatti byte del ByteRange | ValidationReport | Non solleva su byte ostili | TOTAL_PASSED solo per una catena attendibile che copre fino all’EOF |
MainIndication | — | Enum backed da stringa, tre casi | — | — | Valori URN ETSI; vedere l’elenco dei casi qui sotto |
SubIndication | — | Enum backed da stringa, quindici casi | — | — | Valori URN ETSI; vedere l’elenco dei casi qui sotto |
ValidationReport::__construct | MainIndication $mainIndication, ?SubIndication $subIndication, DiagnosticData $diagnosticData, DateTimeImmutable $validationTime, string $validationPolicy = '' | Esito di validazione immutabile (final readonly) | Nuovo report | Non solleva | isPassed(), isFailed(), isIndeterminate(), toArray() |
DiagnosticData::__construct | array $certificateChain, array $timestamps, array $revocationData, string $validationPolicy, string $signatureFormat, array $warnings (tutti con valore predefinito) | Contenitore di evidenze immutabile; solo traccia di audit | Nuovo valore | Non solleva | toArray() serializza i riferimenti per la reportistica |
SignatureDataExtractor::extract | string $signedData, string $signature | SPI: analizza il CMS ed estrae i componenti di validazione | ExtractedSignatureData | SignatureExtractionException quando la firma non può essere analizzata | Interfaccia; disaccoppia il parsing ASN.1 dal motore |
CmsSignatureDataExtractor::extract | string $signedData, string $signature | Estrae e verifica crittograficamente una firma basic PAdES detached | ExtractedSignatureData | SignatureExtractionException solo quando il CMS non può essere analizzato affatto | Un fallimento crypto o di binding restituisce dati con cryptoValid / hashValid a false; non solleva mai per questo |
PdfSignatureDictionaryScanner::scan | string $pdfBytes | Scansione a livello di byte dei dizionari /ByteRange + /Contents con controlli incrociati anti-spoof a fit preciso | list<PdfSignatureOccurrence> | Totale; non solleva mai; i candidati malformati vengono ignorati | Ordinati per fine copertura, dal più precoce |
PathValidatorInterface::validate | array $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = [] | Validazione del percorso RFC 5280 §6.1.4 con elaborazione delle policy | PathValidationResult | PathValidationException su una catena strutturalmente non valida o un limite avversariale superato | La catena è end-entity per prima, ancora per ultima |
PathValidatorInterface::validateWithAiaChasing | array $chain, ?DateTimeImmutable $validationTime = null | Risoluzione AIA degli intermediari mancanti, poi validazione | PathValidationResult | PathValidationException | I fetch sono limitati da timeout e limiti di byte |
CertificateChainValidator | Costruttore: motore, PathValidationOptions, orologio, logger; withDefaults() statico | L’implementazione SPI con i cap avversariali predefiniti | PathValidationResult da entrambi i metodi | PathValidationException | Sollevata anche quando un OpenSSLCertificate non può essere esportato in PEM |
PathValidationOptions::__construct | Cap (maxDepth, maxPolicyFanout, fetchTimeoutSeconds, fetchSizeCapBytes) più flag di policy, ?TrustAnchorStoreInterface $trustAnchors, bool $requireTrustedAnchor | Profondità 32, fanout 64, 5 s per fetch, 10 MiB per fetch; tutti i flag false | Nuove opzioni | Non solleva | Factory: defaults(), strict(), withTrustAnchors() |
PathValidationResult::__construct | bool $valid, string $trustAnchorFingerprint, DateTimeImmutable $validatedAt, array $validPolicies, ?RevocationCheckResult $revocation, bool $trustAnchorTrusted, array $fetchedCertificates, array $failureReasons | Esito immutabile; trustAnchorTrusted predefinito false (fail-closed) | Nuovo valore | Non solleva | L’appartenenza alla fiducia è distinta dalla validità strutturale |
PolicyProcessor | Costruttore: PolicyTreeState $state, PathValidationOptions $options; processCertificate(string $certDer, int $depth, bool $selfIssued), finalizeWrapUp(), tree() | Espansione, mapping e wrap-up dell’albero delle policy RFC 5280 §6.1.4 | void / list<non-empty-string> / PolicyTree | PathValidationException su qualsiasi fallimento di elaborazione delle policy (fail-closed) | Il wrap-up restituisce gli OID delle policy sopravvissute, escludendo anyPolicy |
PolicyTree | attach(PolicyTreeNode $node, PathValidationOptions $options), enforceFanout(...), remove(...), più query di lettura | Lo stato valid_policy_tree con un indice di profondità | Varia per metodo | PathValidationException quando il conteggio delle foglie vive supera il cap di fanout | Espone ANY_POLICY_OID (2.5.29.32.0) |
NameConstraintsChecker::processCertificate | string $certDer, bool $applyNameCheck | Accumula e applica i sottoalberi permessi / esclusi secondo RFC 5280 §6.1.4(g) | void | PathValidationException su un sottoalbero violato, una forma GeneralName non supportata in un vincolo o un cap superato | I nomi non comparabili sono gestiti fail-closed |
TrustAnchorStoreInterface::containsFingerprint | string $anchorDerSha256Hex | Appartenenza tramite SHA-256 esadecimale minuscolo sul certificato DER dell’ancora | bool | Non solleva | La cucitura di fiducia consultata dal validatore di percorso |
BatchSignatureValidator::validate | array $inputs (list<DocumentSignatureInput>) | Validazione di firme multi-documento con caching della revoca per batch | BatchValidationReport | InvalidArgumentException su una lista vuota; una guardia di risorse rifiuta i batch oltre 1000 documenti | Risiede in NextPDF\Enterprise\Signature |
final class AdESValidationEnginepublic function validateBasic(string $signedData, string $signature): ValidationReportpublic function validateWithTime( string $signedData, string $signature, DateTimeImmutable $claimedTime,): ValidationReportpublic function validateWithLongTermData( string $signedData, string $signature, array $dssData,): ValidationReportpublic function validateArchivalTimestampChain( string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null,): ValidationReportpublic function validate( array $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = [],): PathValidationResult;public function validateWithAiaChasing( array $chain, ?DateTimeImmutable $validationTime = null,): PathValidationResult;public static function withDefaults( ?ClockInterface $clock = null, ?AiaChaser $aiaChaser = null, ?LoggerInterface $logger = null,): selfpublic function containsFingerprint(string $anchorDerSha256Hex): bool;public function extract(string $signedData, string $signature): ExtractedSignatureData;public function scan(string $pdfBytes): arraypublic function validate(array $inputs): BatchValidationReportEnum di indicazione. Casi di MainIndication: TOTAL_PASSED, TOTAL_FAILED, INDETERMINATE. I valori di backing seguono lo schema urn:etsi:019102:mainindication:total-passed (minuscolo, con trattini). Casi di SubIndication: HASH_FAILURE, SIG_CRYPTO_FAILURE, REVOKED, EXPIRED, NOT_YET_VALID, NO_POE, TRY_LATER, CERTIFICATE_CHAIN_GENERAL_FAILURE, FORMAT_FAILURE, REVOKED_CA_NO_POE, CRYPTO_CONSTRAINTS_FAILURE, POLICY_PROCESSING_FAILURE, REVOCATION_OUT_OF_BOUNDS_NO_POE, NO_SIGNING_CERTIFICATE_FOUND, TIMESTAMP_ORDER_FAILURE. Ciascuno è backed da urn:etsi:019102:subindication:<CASE_NAME> con il nome esatto del caso.
Contratto di comportamento
Sezione intitolata “Contratto di comportamento”- Report in ingresso, report in uscita. I quattro punti di ingresso del motore restituiscono un
ValidationReportper input ostili invece di sollevare. UnaSignatureExtractionExceptioncatturata instrada verso il percorso di guardia; unaPathValidationExceptioncatturata mappa aTOTAL_FAILED/CERTIFICATE_CHAIN_GENERAL_FAILURE. - Ordine della validazione basic. Prima il controllo del formato; una struttura non analizzabile è
TOTAL_FAILED/FORMAT_FAILURE(EN 319 102-1 §5.3.4). Poi il digest (HASH_FAILURE) e la verifica crittografica (SIG_CRYPTO_FAILURE), corrispondenti agli esiti dei building block di EN 319 102-1 §5.2.7.4. Il digest viene ricalcolato dal verifier e confrontato con l’attributo firmatomessageDigest(RFC 5652 §5.6); i digest forniti dal produttore non sono mai considerati attendibili. - Gli algoritmi deboli degradano. Una firma che verifica sotto SHA-1, o con un binding debole del certificato di firma, restituisce
INDETERMINATE/CRYPTO_CONSTRAINTS_FAILURE, maiTOTAL_PASSED. Il percorso temporale riafferma questo, così una firma debole non viene mai riciclata in un esito valido nel tempo. - Gate di provenienza della revoca. I flag di revoca dell’extractor sono consultati solo quando l’extractor ha effettivamente eseguito un controllo di revoca (
revocationCheckedtrue). Un valore predefinito non controllato non è né “verificato non revocato” né un triggerREVOKED. L’evidenza di revoca è stabilita dal percorso DSS. - Propagazione del non-esito-positivo. I percorsi con tempo e a lungo termine non promuovono mai un risultato basic non positivo. Esiste un’unica eccezione: un basic
INDETERMINATE/REVOKEDviene risolto rispetto a$claimedTime; la revoca al momento del tempo dichiarato o prima di esso èTOTAL_FAILED/REVOKED. Ciò rispecchia lo schema di EN 319 102-1 §5.3.4 di risolvere un indeterminato relativo alla revoca con evidenza temporale. Quando il confronto non può essere eseguito, il report basic irrisolto viene propagato verbatim. - Binding rigoroso della marca temporale di firma (fail-closed; rottura BC). Quando il CMS trasporta un attributo non firmato
id-aa-timeStampToken, la sua presenza attiva l’enforcement sia nel percorso con tempo sia in quello a lungo termine; non esiste una modalità solo-avviso. La cardinalità deve essere esattamente un attributo con esattamente un valore (EN 319 122-1 §5.3); qualsiasi altra forma èTOTAL_FAILED/FORMAT_FAILURE. Il token deve verificare crittograficamente da un capo all’altro; un token non verificabile, un conflitto parser-differential o una mancata corrispondenza dell’imprint èINDETERMINATE/TIMESTAMP_ORDER_FAILURE. Un algoritmo di imprint non supportato o SHA-1 èINDETERMINATE/CRYPTO_CONSTRAINTS_FAILURE. La regola di binding è RFC 3161 Appendix A: ilmessageImprintdel token deve essere uguale all’hash degli ottetti del valoresignaturedi SignerInfo, confrontati a tempo costante. - Gate del percorso a lungo termine. Nel percorso annotato con la clausola 5.4 la marca temporale di firma vincolata riceve inoltre la valutazione del certificato TSA al
genTimedel token; un’ancora non attendibile èINDETERMINATE/CERTIFICATE_CHAIN_GENERAL_FAILURE, mai un esito positivo.NetworkPolicy::STRICT_OFFLINEcon materiale DSS incorporato insufficiente restituisceINDETERMINATE/TRY_LATER. Le rilevazioni di prova di esistenza, revoca DSS e catena di archiviazione fanno ciascuna short-circuit aINDETERMINATEcon una sotto-indicazione mappata. - Gate della catena di archiviazione. Nessun DocTimeStamp presente è
INDETERMINATE/NO_POE. Un ByteRange strutturalmente non conforme èTOTAL_FAILED/FORMAT_FAILURE. Ogni token deve verificare, vincolare il proprio imprint agli esatti byte coperti dal ByteRange e superare il mapping delle facet TSA-at-genTime (EXPIRED,NOT_YET_VALID,REVOKED_CA_NO_POE,CERTIFICATE_CHAIN_GENERAL_FAILUREoTRY_LATERin strict-offline). L’ordinamento è imposto:genTimenon decrescente, copertura in progressione stretta e token successivi che contengono il buco/Contentsdel token precedente. Il token più recente deve coprire il byte finale; i byte in coda sonoTIMESTAMP_ORDER_FAILURE. UngenTimepiù di 300 secondi avanti rispetto all’orologio del verifier èTIMESTAMP_ORDER_FAILURE. - La diagnostica non decide mai. Le voci di prova di esistenza di
DiagnosticData::$timestampssono solo traccia di audit. Non cambiano mai un’indicazione, e l’accumulatore si azzera a ogni punto di ingresso. - I limiti Pki precedono la crittografia. I cap di
PathValidationOptions(profondità 32, fanout delle policy 64, 5 s e 10 MiB per fetch) sono controllati prima del lavoro costoso.PathValidationResult::$trustAnchorTrustedè distinto da$valid;requireTrustedAnchorrende non valido un terminus non confermato.strict()abilitarequireExplicitPolicy, il trasporto di revoca hard-fail erequireTrustedAnchor. La validità del percorso è relativa all’ancora secondo RFC 5280 §6.1: un percorso valido inizia da un’ancora di fiducia fornita come input. - Superficie batch.
BatchSignatureValidator::validate()sollevaInvalidArgumentExceptionper una lista vuota e rifiuta i batch oltre 1000 documenti tramite una guardia di risorse. PHP possiede tutta la validazione crittografica in quella pipeline.
Casi limite e modalità di fallimento
Sezione intitolata “Casi limite e modalità di fallimento”- Il motore predefinito non ha extractor.
new AdESValidationEngine()esegue solo controlli di guardia: firma o dati firmati vuoti sonoTOTAL_FAILED; qualsiasi coppia non vuota si risolve inINDETERMINATE/NO_SIGNING_CERTIFICATE_FOUND, maiTOTAL_PASSED. IniettareNextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractorper ottenere la verifica crittografica. - Il controllo di fiducia TSA predefinito non ha store. Ogni catena TSA riporta quindi non attendibile, così gli esiti della marca temporale di firma di archiviazione e a lungo termine restano
INDETERMINATE. Fornire le ancore tramitevalidateArchivalTimestampChain(..., $anchors)o unTsaCertificateAtGenTimeCheckconfigurato. $pdfBytesvuoto.validateArchivalTimestampChain('')restituisceTOTAL_FAILED/FORMAT_FAILURE.- Le marche temporali di firma precedenti alla correzione non possono passare. I token prodotti da versioni di NextPDF antecedenti alla correzione del binding rigoroso hanno imprintato un input differente. Falliscono permanentemente il binding di Appendix A; ri-firmare e ri-marcare temporalmente per ripristinare un risultato positivo. Questa è una rottura BC deliberata e documentata.
- DocTimeStamp duplicati o sovrapposti. Un duplicato nella stessa revisione, copertura uguale o sovrapposta, o un token successivo che non contiene il buco di firma del token precedente falliscono il gate di ordinamento.
- Lo scanner è totale e a livello di byte.
scan()ignora silenziosamente i candidati malformati o spoofati; un/ByteRangeesca all’interno di un content stream viene rifiutato. Non risolve oggetti indiretti né percorre la tabella dei cross-reference. - Copertura, non raggiungibilità.
validateArchivalTimestampChain()dimostra la copertura crittografica del byte-range fino alla fine del file. L’analisi di raggiungibilità a livello di oggetto (per esempio, una radice di documento ri-puntata all’interno di una revisione coperta) è dichiarata fuori ambito. - L’uso diretto di Pki solleva. Chiamare direttamente le implementazioni di
PathValidatorInterfacefa emergerePathValidationExceptionper catene strutturalmente non valide, cap superati, forme di vincolo non supportate ed esportazione PEM fallita di un handleOpenSSLCertificate. Il motore cattura questa classe; i tuoi chiamanti devono gestirla.
Comportamento in modalità FIPS
Sezione intitolata “Comportamento in modalità FIPS”La superficie di verifica accetta RSA PKCS#1 v1.5 con SHA-2 ed ECDSA su P-256/P-384/P-521. I token RSASSA-PSS, EdDSA e SHA-3 falliscono chiuso come non supportati; SHA-1 degrada a CRYPTO_CONSTRAINTS_FAILURE. Sotto il profilo crypto-policy FIPS 140-3 Enterprise (documentato con il modulo security), il vincolo si applica a quali algoritmi vengono accettati; il flusso di validazione in sé — ricalcolo del digest, controlli della firma, binding, validazione del percorso — resta invariato. NextPDF non detiene alcun certificato FIPS 140-3 e questa pagina non ne rivendica alcuno.
Conformità
Sezione intitolata “Conformità”| Affermazione | Standard | Clausola |
|---|---|---|
| La validazione della Basic Signature è un building block riutilizzabile per la validazione con marca temporale e con tempo. | ETSI EN 319 102-1 | §5.3.1 |
Il fallimento di integrità mappa a HASH_FAILURE; un controllo della firma fallito mappa a SIG_CRYPTO_FAILURE. | ETSI EN 319 102-1 | §5.2.7.4 |
| Il controllo del formato viene eseguito per primo e un non-esito-positivo arresta il processo. | ETSI EN 319 102-1 | §5.3.4 |
| Un indeterminato relativo alla revoca può essere risolto con evidenza temporale. | ETSI EN 319 102-1 | §5.3.4 |
| Un percorso di certificazione valido inizia da un’ancora di fiducia fornita come input. | RFC 5280 | §6.1 |
Il verifier ricalcola il digest del contenuto; deve essere uguale all’attributo firmato messageDigest. | RFC 5652 | §5.6 |
Il messageImprint della marca temporale di firma esegue l’hash del valore del campo signature di SignerInfo. | RFC 3161 | Appendix A |
L’attributo signature-time-stamp trasporta esattamente un AttributeValue. | ETSI EN 319 122-1 | §5.3 |
Tutte le clausole sono parafrasate; NextPDF non riproduce testo normativo. NextPDF non rivendica alcuna conformità o certificazione AdES / PAdES. Il supporto di uno standard non è conformità ad esso, e la conformità non è certificazione — NextPDF non detiene alcuna certificazione e non ne concede alcuna. Il motore implementa le procedure di validazione citate come capacità; non è un servizio di validazione qualificato o certificato, e un report TOTAL_PASSED è un’affermazione crittografica, non una determinazione legale. I valori enum riutilizzano lo schema di identificatore URN ETSI per l’interoperabilità dei dati di report; tale riutilizzo non afferma alcuna approvazione.
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Mapping delle etichette di clausola. Il sorgente del package annota i punti di ingresso come clausole 5.2, 5.3 e 5.4 di EN 319 102-1. Il corpus di conformità colloca il processo di validazione della Basic Signature stesso alla clausola 5.3, con il building block crittografico a 5.2.7.4. Questa pagina cita i numeri di clausola recuperati; il contratto di comportamento, non l’etichetta, è autoritativo.
- Test deterministici. Ogni confronto temporale passa attraverso l’iniettato
ClockInterfacePSR-20. Iniettare un orologio congelato per testare i controlli di finestra, il limite di scarto del genTime di 300 secondi e le decisioni di freschezza CRL. - Composizione. Tutti i collaboratori del motore sono iniettati via costruttore e opzionali, con valori predefiniti fail-closed. Il validatore di percorso predefinito è
CertificateChainValidator::withDefaults()sull’orologio del motore; le opzioni predefinite mantengono l’elaborazione delle policy e dei name-constraint un no-op per input conformi e non vincolati. - Namespace. La superficie del motore risiede in
NextPDF\Enterprise\Security\Validation, la superficie di validazione del percorso inNextPDF\Enterprise\Security\Pkie l’orchestratore batch inNextPDF\Enterprise\Signature. - Igiene dei report. I report sono immutabili e serializzabili tramite
toArray(). Il contesto diagnostico si azzera a ogni punto di ingresso, così un report non trasporta mai evidenza da un’esecuzione precedente sulla stessa istanza del motore.
Vedere anche
Sezione intitolata “Vedere anche”- Verifica delle firme: verifica crittografica AdES / PAdES — la pagina della capacità: flusso di lavoro, tabella degli algoritmi, note di aggiornamento.
- Firma — Riferimento approfondito — il lato produttore PAdES B-LT / B-LTA.
- Validazione — Riferimento approfondito — controlli strutturali delle policy senza crittografia.
- Sicurezza — Riferimento approfondito — la superficie di sicurezza Enterprise combinata, incluso il profilo FIPS.
- Mappatura delle baseline PAdES — B-B, B-T, B-LT, B-LTA tra le edizioni.
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 di meccanismo, i nomi di file di runbook e i prefissi di ticket sono fuori ambito.