Job di firma PFX incrementale

L'operazione sign supporta un profilo incrementale validato che preserva l'esatta revisione PDF originale e ogni firma crittografica esistente, restituendo al tempo stesso un artefatto firmato separatamente

Scelta del profilo

{"schemaVersion":1,"type":"sign","profile":"pfx-incremental-document",
 "pfxFile":"C:/keys/signer.pfx","pfxPassword":"password",
 "fieldName":"ApprovalTwo","existingField":true,
 "budget":{"memoryBytes":268435456,"outputBytes":134217728,
           "resultBytes":16777216,"timeMilliseconds":60000,
           "objectCount":1000000,"pageCount":1024}}

Il profilo default pfx-unsigned-document conserva il comportamento originale e accetta sorgenti senza alcun campo firma; crea un nuovo campo usando page, x1, y1, x2 e y2 e ripristina il grafo sorgente prima della pubblicazione

pfx-incremental-document seleziona il nuovo profilo; incremental: true è un selettore equivalente quando profile è omesso, ed è in conflitto con un profilo esplicitamente diverso

existingField: true riempie il campo firma nominato e vuoto senza aggiungerne un altro; in caso contrario l'operazione crea un nuovo campo, e page e il rettangolo identificano il suo widget

Il default di fieldName è Signature1 e accetta da 1 a 1024 byte UTF-8; existingField richiede un profilo incrementale, un campo firma corrispondente e un valore V assente o null

Il bit 1 read-only di Ff e i flag interi malformati o fuori range vengono rifiutati prima della preparazione; i dizionari SV e Lock ereditati vengono risolti con nomi PDF semanticamente univoci e traversal dei padri limitata

Seed values e lock dei campi

digestMethod seleziona il digest CMS reale SHA256, SHA384 o SHA512; SHA256 è il default, mentre cades: true seleziona ETSI.CAdES.detached e include l'attributo signing-certificate-v2 che vincola il certificato di firma effettivo

reason, location e contactName sono stringhe JSON UTF-8 scritte come stringhe PDF Unicode; i seed reason obbligatori confrontano i propri valori Unicode, incluso il valore speciale del punto singolo che richiede l'omissione del reason

I vincoli SV obbligatori verificano l'handler reale, il SubFilter CMS, la versione di firma supportata, il digest, il reason, il permesso di certificazione, l'attestazione legale e la modalità LockDocument; un timestamp obbligatorio usa il trasporto applicativo e il workflow di trust esplicito descritto in Windows signing timestamps, l'evidenza di revoca firmata obbligatoria usa firma CRL e OCSP autenticata, e gli appearance nominati obbligatori usano preset di appearance firma generati reali

Le proprietà SVCert obbligatorie validano il certificato foglia PFX reale e la catena issuer inclusa, i byte di certificato permessi, gli OID di certificate policy, i key usage bit e gli attributi DN del subject in Unicode prima della firma

credentialSourceURL fornisce una provenienza delle credenziali dichiarata dall'applicazione per un URL SVCert obbligatorio; la libreria confronta l'URL dichiarato e il URLType supportato senza aprire quell'endpoint né autenticare un'identità di trasporto

I field lock All, Include ed Exclude vengono scritti come dizionario SigFieldLock indiretto e un riferimento FieldMDP corrispondente vincolato al Catalog del documento; i nomi dei campi usano stringhe PDF Unicode e restano cifrati nei documenti cifrati

Un valore P del Lock firmato limita le revisioni successive usando la policy firmata originale dei campi, indipendentemente da qualunque permesso DocMDP; le seconde firme permesse preservano l'esatta revisione precedente e il CMS, mentre un campo locked o una modifica P1 viene rifiutata prima della pubblicazione

Il lookup delle policy decodifica gli escape dei name PDF esattamente una volta, inclusi i nomi Parent ereditati; i dizionari con nomi semantici duplicati e padri non validi o ciclici vengono rifiutati prima della pubblicazione, mentre i nomi con escape validi conservano i propri byte sorgente

contentsBytes ha default 16384 e accetta da 1024 a 1048576; reason, location e contactName popolano il nuovo dizionario firma

Certificazione e attestazioni legali

certificationPermission ha default 0 per la firma di approvazione; 1, 2 o 3 crea una firma di certificazione con il permesso DocMDP richiesto, vincola Catalog Perms DocMDP al dizionario firma indiretto reale e conserva ogni trasformazione FieldMDP indipendente

La certificazione deve essere la prima firma, e un documento può contenere una sola firma di certificazione; permessi Catalog malformati, riferimenti irrisolti e valori DocMDP senza un binding a un campo firmato originale vengono rifiutati

legalAttestation è una stringa Unicode opzionale per la firma di certificazione e viene scritta in Catalog Legal Attestation; una lista SV LegalAttestation obbligatoria deve contenere il testo selezionato, mentre una lista obbligatoria vuota richiede l'omissione

Le firme di certificazione P2 e P3 esistenti permettono firme di approvazione successive quando i lock dei campi e la policy di revisione lo consentono; le firme P1 e i campi locked rifiutano le modifiche prima della pubblicazione binaria

Contratto della sorgente

Il profilo dei job incrementali accetta una sorgente originale trattenuta, inclusi PDF cifrati supportati, e un grafo di oggetti caricato non modificato; fornite password nell'operazione sign per una sorgente cifrata, separatamente da pfxPassword

La password della sorgente autentica uno snapshot raw indipendente, inizializza il contesto di cifratura originale e riapre il candidato firmato; la revisione incrementale risultante preserva il prefisso ciphertext originale, il dizionario di sicurezza e l'ID permanente del documento

La decifratura può marcare internamente oggetti come dirty o rimuovere un dizionario di sicurezza dal grafo decifrato; l'operazione confronta questi stati e serializzazioni di oggetti limitate con una baseline sorgente appena autenticata, rifiutando al tempo stesso modifiche reali del grafo e tutti gli stati di oggetti flushed

Con una password utente, un campo firma esistente richiede il permesso di form-fill o annotazioni, e un nuovo widget firma richiede il permesso di annotazioni; una password owner autenticata autorizza entrambe le operazioni, nei limiti delle policy di firma esistenti

SaveLoadedDocumentToStream può cambiare lo stato di serializzazione; quando firmate un grafo salvato o modificato, ricaricate i byte salvati in un nuovo handle e firmate quella revisione

Tenete lo storage della sorgente originale stabile per l'intera vita dell'handle; i file job negano la write sharing durante il caricamento e la preparazione del proprio snapshot

L'handle originale conserva i propri conteggi di campi, identità dei campi esistenti, valori del form, byte sorgente e impostazioni di launch e decode precedenti; ogni firma riuscita restituisce documentUpdated: false, e i fallimenti di firma lasciano l'handle disponibile per query, salvataggio o una richiesta valida successiva

I file job rifiutano un percorso di output uguale o alias del file di input, inclusi gli hard link; le API dirette su stream rifiutano alias riconoscibili di source-stream e source-file, e i chiamanti devono inoltre tenere lo storage di output opaco dei callback distinto dallo storage di input

Preparazione e validazione

L'operazione copia i byte sorgente raw in uno snapshot temporaneo creato in modo esclusivo, apre un clone incrementale indipendente, accoda il placeholder tramite SaveIncrementalUpdate limitato e riempie il CMS detached tramite il firmatore nativo di stream PFX

Il PFX resta aperto con write sharing negato dal preflight della dimensione fino alla firma; i file temporanei usano CREATE_NEW e vengono rimossi solo quando l'operazione ne possiede la creazione

Il candidato firmato deve contenere l'esatto prefisso di byte sorgente e i conteggi attesi di campi form e firma; la nuova firma deve verificarsi nel suo campo selezionato, ogni firma popolata in precedenza deve ancora verificarsi, e l'analisi di revisione di ogni vecchia firma deve accettare i vincoli DocMDP, FieldMDP, usage-rights e identity

I vecchi campi non popolati vengono trattenuti senza essere contati in preservedSignatures; le firme esistenti malformate, non valide o in violazione di policy causano il rifiuto prima della pubblicazione binaria

La verifica delle firme esistenti controlla l'integrità CMS sui byte firmati e la policy di revisione nativa; quando timestamp è richiesto per la nuova firma, la sua risposta valida separatamente il trust TSA esplicito e l'evidenza di revoca configurata prima della pubblicazione

Budget e pubblicazione

Il tetto effettivo dell'output è min(outputBytes, memoryBytes / 8) e include l'intero prefisso sorgente, gli oggetti accodati, l'xref e la riserva della firma; effectiveOutputLimit riporta il tetto applicato

Il candidato non firmato e l'output firmato sono limitati separatamente da quel tetto, i byte PFX sono limitati a memoryBytes / 8, e i budget di decodifica di baseline sorgente, clone e candidato sono limitati separatamente a memoryBytes / 8 con soglie di spill su file non superiori a 1 MiB

Sono budget di operazione e buffer, non una garanzia rigorosa sul RSS del processo; crittografia, metadati degli oggetti, analisi di revisione e la sorgente già caricata dal chiamante possono richiedere memoria residente aggiuntiva

I controlli di cancellazione e tempo trascorso si applicano alla copia sorgente, alla serializzazione e copia del delta, alle letture del candidato, alle letture della verifica firme, alle letture dell'analisi di revisione e alla pubblicazione via callback; i fallimenti sticky degli stream nativi conservano la propria categoria di budget o cancellazione al confine del job

L'output binario viene messo in staging e validato prima del primo output callback, e la dimensione del result JSON viene controllata prima della pubblicazione binaria; l'output via callback in sé non è atomico, quindi un callback binario o di risultato fallito può lasciare byte che il chiamante deve scartare

I file job scrivono su un candidato di proprietà nella stessa directory, ne fanno il flush, chiudono gli handle di sorgente e output e sostituiscono atomicamente un target distinto dopo la validazione; i fallimenti preservano una destinazione esistente

Il successo restituisce mediaType: application/pdf, fieldName, profile, incremental, existingField, certificationPermission, revocationInfo, appearanceProfile, preservedSignatures, effectiveOutputLimit, outputBytes e documentUpdated: false

Accettazione di replay

$env:HOTPDF_SUPPRESS_AUTO_LAUNCH = '1'
./Tests/CABI/Run-IncrementalSigningAcceptance.ps1 -BuildDLL -CheckFPC

Il runner scopre RAD Studio tramite la sua chiave di registro RootDir, accetta gli override RADStudioRoot e PythonExecutable e usa la toolchain FPC configurata quando CheckFPC è selezionato; FPCOnly fa il replay solo di quei target nativi, mentre OpenSSLWin32Library e OpenSSLWin64Library selezionano le librerie runtime corrispondenti per ogni architettura

Il runner non-GUI verifica sia le API native Win32 che Win64 e le DLL C ABI reali usando callback parziali, campi vuoti esistenti, firme precedenti, seed values obbligatori, CAdES reale SHA384 e SHA512, metadati Unicode, seconde firme permesse e locked, proprietà reali dei certificati PFX, trasformazioni di field lock AES-128 e AES-256, restrizioni di permessi e credenziali owner, password errate, grafi decifrati dirty, snapshot cifrati esatti della sorgente, recovery del writer cifrato in place, fixture CMS reali DocMDP P1 e P2, budget, cancellazione, fallimenti di callback e riuso della sorgente dopo i fallimenti

Le verifiche indipendenti pypdf, MuPDF e OpenSSL provano i prefissi precedenti esatti e i byte range, cifratura e ID permanenti invariati, testo originale ricercabile, valori CMS vecchi e nuovi validi, l'esenzione dalla cifratura del Contents della firma e il rifiuto di contenuto firmato modificato; independent-proof.json registra i byte range e i risultati delle prove

Argomenti correlati

Document operations, CopyLoadedSourceToStream, SaveIncrementalUpdate, EHPDFIncrementalOutputBudget