Risoluzione dei problemi: errori di firma e marche temporali
Queste schede riguardano gli errori di firma che il motore solleva tramite NextPDF\Exception\SignatureException e NextPDF\Security\Signature\Exception\SignatureLevelUnreachableException. Ogni scheda indica il metodo factory o la classe esatti, così da poter confermare la causa dal messaggio e da getContext() senza doverla dedurre.
Una nota sulla terminologia: il motore non certifica che una firma sia valida né che un documento sia protetto. Si limita a segnalare l’errore rilevato. Considerare ogni soluzione come un passaggio per rimuovere la causa segnalata.
Voce: il livello PAdES “B-LT” o “B-LTA” non può essere prodotto
Sezione intitolata “Voce: il livello PAdES “B-LT” o “B-LTA” non può essere prodotto”- Sintomo.
SignatureExceptioncon il messaggio terminante innextpdf/enterprise package is required for B-LT/B-LTA signatures. - Causa probabile. Manca il provider della capacità di convalida a lungo termine. B-LT e B-LTA incorporano il materiale di revoca e una marca temporale di archiviazione; questo provider è incluso in
nextpdf/enterprise. - Evidenza / diagnosi. Il factory
SignatureException::ltvCapabilityMissing()produce esattamente questo messaggio.getContext()restituiscesignature_levelimpostato sul livello richiesto. - Soluzione.
- Installare il provider: eseguire
composer require nextpdf/enterprise. - Rieseguire la chiamata di firma.
- Se non è possibile installare il provider, richiedere invece
B-BoB-T, prodotti dal pacchetto core.
- Installare il provider: eseguire
- Correlato. Riferimento delle eccezioni.
Voce: il livello di firma è irraggiungibile e la chiamata viene rifiutata
Sezione intitolata “Voce: il livello di firma è irraggiungibile e la chiamata viene rifiutata”- Sintomo.
SignatureLevelUnreachableExceptioncon un messaggio nella formaPAdES level "<x>" is unreachable (highest achievable: "<y>"). - Causa probabile. Il livello di conformità richiesto richiede un’infrastruttura non disponibile al momento della firma — il più delle volte un’autorità di marca temporale per B-T e superiori. Il motore adotta il fail-closed: non effettua silenziosamente un downgrade per poi dichiarare il livello superiore.
- Evidenza / diagnosi.
getContext()restituiscerequestedLevel,highestAchievableLevelereason. Il camporeasonindica la lacuna infrastrutturale. Questa è l’impostazione predefinita fail-closed, introdotta per impedire che un documento dichiari un livello che non soddisfa. - Soluzione.
- Leggere il campo
reasonper individuare l’infrastruttura mancante. - Fornire il componente mancante — ad esempio, configurare un’autorità di marca temporale — e rieseguire la chiamata.
- Per accettare intenzionalmente un livello inferiore, passare
allowDegradation: trueaPadesOrchestrator. La chiamata produce quindihighestAchievableLevele segnala il livello effettivamente prodotto.
- Leggere il campo
- Correlato. Cifratura e autorizzazioni.
Voce: il client dell’autorità di marca temporale è richiesto ma assente
Sezione intitolata “Voce: il client dell’autorità di marca temporale è richiesto ma assente”- Sintomo.
SignatureExceptioncon la terminazioneTSA client is required for level <x> but none was provided. - Causa probabile. Una richiesta B-T, B-LT o B-LTA richiede un client dell’autorità di marca temporale, ma nessun client è stato collegato all’orchestrator.
- Evidenza / diagnosi. Il factory
SignatureException::tsaRequired()produce questo messaggio;getContext()contiene ilsignature_levelrichiesto. - Soluzione.
- Configurare un client dell’autorità di marca temporale e passarlo all’orchestrator.
- Rieseguire la chiamata.
- Per produrre un livello che non necessita di marca temporale, richiedere
B-B.
- Correlato. Riferimento delle eccezioni.
Voce: l’URL dell’endpoint dell’autorità di marca temporale è vuoto
Sezione intitolata “Voce: l’URL dell’endpoint dell’autorità di marca temporale è vuoto”- Sintomo.
SignatureExceptioncon la terminazioneTSA endpoint URL is empty. - Causa probabile. Un client dell’autorità di marca temporale è stato costruito con un URL dell’endpoint vuoto.
- Evidenza / diagnosi. Il factory
SignatureException::tsaUrlEmpty()produce questo messaggio. Si tratta di un difetto di configurazione, non di un errore di rete. - Soluzione.
- Impostare un URL dell’endpoint non vuoto sul client dell’autorità di marca temporale, ad esempio
https://timestamp.example.com/tsa. - Se il livello richiesto non richiede la marca temporale, rimuovere invece il collegamento del client dell’autorità di marca temporale.
- Rieseguire la chiamata.
- Impostare un URL dell’endpoint non vuoto sul client dell’autorità di marca temporale, ad esempio
- Correlato. Riferimento delle eccezioni.
Voce: il segnaposto della firma è assente dal buffer
Sezione intitolata “Voce: il segnaposto della firma è assente dal buffer”- Sintomo.
SignatureExceptioncon la terminazioneno /Contents <…> field found in PDF buffer (signature placeholder missing). - Causa probabile. La fase di firma è stata eseguita su un buffer privo di un contenitore di firma riservato, quindi non esiste alcuno spazio in cui scrivere la firma.
- Evidenza / diagnosi. Il factory
SignatureException::signatureContentsNotFound()produce questo messaggio. - Soluzione.
- Assicurarsi che il campo della firma e il relativo segnaposto siano scritti prima dell’esecuzione della fase di firma.
- Rieseguire la pipeline in modo che il segnaposto esista all’avvio della firma.
- Correlato. Riferimento delle eccezioni.
Voce: lo stato di revoca è sconosciuto (responder OCSP ha rifiutato)
Sezione intitolata “Voce: lo stato di revoca è sconosciuto (responder OCSP ha rifiutato)”- Sintomo.
SignatureExceptioncon la terminazioneOCSP responder returned non-successful OCSPResponseStatus "<status>". - Causa probabile. Il responder OCSP non ha restituito uno stato
successful, quindi non ha prodotto alcuna asserzione di revoca. Il motore segue RFC 6960 §4.2.1, che cita nel sorgente: un corpo di risposta popolato è consentito solo per lo statosuccessful (0). Il motore rifiuta di trattare una risposta rifiutata come un risultato di attendibilità positiva. - Evidenza / diagnosi. Il factory
SignatureException::nonSuccessfulOcspResponseStatus()produce questo messaggio e indica lo stato segnalato, ad esempiotryLaterointernalError. Un byte di stato riservato o sconosciuto produce inveceSignatureException::reservedOcspResponseStatus(). - Soluzione.
- Individuare lo stato nel messaggio. Per uno stato transitorio come
tryLater, riprovare più tardi il recupero delle informazioni di revoca. - Per
unauthorizedomalformedRequest, verificare l’URL della richiesta OCSP e il certificato atteso dal responder. - Non sopprimere l’errore per ottenere un artefatto B-LT o B-LTA; l’asserzione di revoca fa parte di quel livello.
- Individuare lo stato nel messaggio. Per uno stato transitorio come
- Correlato. Riferimento delle eccezioni.
Voce: una voce della catena di certificati non viene decodificata
Sezione intitolata “Voce: una voce della catena di certificati non viene decodificata”- Sintomo.
SignatureExceptioncon la terminazionefailed to base64-decode PEM body — input is not valid PEM. - Causa probabile. Una voce della catena di certificati non è un PEM valido — in genere per troncamento, un carattere estraneo o un blob DER binario fornito dove era atteso PEM.
- Evidenza / diagnosi. Il factory
SignatureException::pemDecodingFailed()produce questo messaggio durante l’assemblaggio della catena. - Soluzione.
- Esaminare ogni certificato della catena per individuare caratteri estranei o troncamenti.
- Riesportare il certificato interessato in forma PEM.
- Rieseguire la chiamata di firma.
- Correlato. Cifratura e autorizzazioni.
Voce: il tipo di chiave privata non corrisponde all’algoritmo
Sezione intitolata “Voce: il tipo di chiave privata non corrisponde all’algoritmo”- Sintomo.
SignatureExceptioncon la terminazioneexpected private key of type "<x>" for the configured algorithm but got "<y>". - Causa probabile. La chiave privata caricata non corrisponde all’algoritmo di firma configurato — ad esempio una chiave RSA con una selezione ECDSA.
- Evidenza / diagnosi. Il factory
SignatureException::unexpectedKeyType()produce questo messaggio e indica sia la classe di chiave attesa sia quella effettiva. - Soluzione.
- Verificare che la coppia certificato/chiave corrisponda all’algoritmo selezionato.
- Modificare la selezione dell’algoritmo in modo che corrisponda alla chiave, oppure caricare la chiave che corrisponde all’algoritmo.
- Rieseguire la chiamata di firma.
- Correlato. Riferimento delle eccezioni.
Voce: la chiave o il materiale di firma Ed25519 è malformato
Sezione intitolata “Voce: la chiave o il materiale di firma Ed25519 è malformato”- Sintomo.
SignatureExceptioncon una terminazione che indica una discrepanza di lunghezza Ed25519 — ad esempioEd25519 signature length <n> ≠ expected 64 bytes, oppureEd25519 round-trip self-verify failed. - Causa probabile. La build di crittografia del runtime ha restituito materiale di chiave o di firma di lunghezza errata, oppure una firma appena prodotta non è stata verificata rispetto alla propria chiave pubblica. Il motore cita RFC 8032 §3.4 nel sorgente, che fissa a 64 byte una firma Ed25519 detached. Il motore interrompe l’operazione anziché emettere materiale che non è in grado di autoverificare.
- Evidenza / diagnosi. I factory pertinenti sono
SignatureException::ed25519SignatureMalformed(),::ed25519RoundTripVerifyFailed(),::ed25519KeyParseFailed(),::ed25519SeedInvalid(),::ed25519SecretKeyMalformed()e::ed25519PublicKeyInvalid(). Ciascuno indica la lunghezza osservata. - Soluzione.
- Reinstallare l’estensione PHP libsodium; una build incompleta o danneggiata è la causa documentata del materiale di lunghezza errata.
- Verificare che la chiave sia una chiave Ed25519 e che OpenSSL sia 1.1.1 o più recente.
- Rieseguire la chiamata di firma.
- Correlato. Riferimento delle eccezioni.
Voce: il dizionario della marca temporale di archiviazione non è stato emesso
Sezione intitolata “Voce: il dizionario della marca temporale di archiviazione non è stato emesso”- Sintomo.
SignatureExceptioncon la terminazioneno /Type /DocTimeStamp dictionary was emitted into the PDF buffer. - Causa probabile. Il ciclo di archiviazione B-LTA è stato eseguito, ma il dizionario della marca temporale del documento non ha mai raggiunto il buffer; di conseguenza, l’artefatto risulterebbe un B-LTA scritto a metà. Il motore rifiuta di restituirlo.
- Evidenza / diagnosi. Il factory
SignatureException::documentTimestampNotEmitted()produce questo messaggio. È un errore di post-condizione sollevato durante la finalizzazione. - Soluzione.
- Considerare l’output come scartato; non distribuire l’artefatto parziale.
- Rieseguire la pipeline B-LTA con un’autorità di marca temporale raggiungibile.
- Se l’errore si ripete, acquisire
getContext()e l’eccezione precedente concatenata per una segnalazione di difetto.
- Correlato. Riferimento delle eccezioni.
Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Questi factory impostano
cert_infosu un subject o un’impronta digitale solo quando è disponibile; uncert_infovuoto è previsto per gli errori di capacità e di configurazione. - Una richiesta B-LT o B-LTA priva di un client HTTP configurato solleva
SignatureException::httpClientMissing()— il recupero delle informazioni di revoca richiede un client PSR-18 passato all’orchestrator. - Un certificato basato su HSM privo di un’implementazione del signer solleva
SignatureException::hsmSignerMissing(); collegare il signer al certificato prima della firma.
Vedere anche
Sezione intitolata “Vedere anche”Glossario: PAdES livello · asserzione di revoca