Jobs de assinatura PFX incremental

A operação sign suporta um perfil incremental validado que preserva a revisão original exata do PDF e cada assinatura criptográfica existente, retornando um artefato assinado separadamente

Selecionando um perfil

{"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}}

O perfil default pfx-unsigned-document retém o comportamento original e aceita origens sem nenhum campo de assinaturas; ele cria um campo novo usando page, x1, y1, x2 e y2, e restaura o grafo da origem antes da publicação

pfx-incremental-document seleciona o perfil novo; incremental: true é um selector equivalente quando profile é omitido, e conflita com um profile explicitamente diferente

existingField: true preenche o campo de assinaturas nomeado e vazio sem adicionar outro campo; caso contrário a operação cria um campo novo, e page e retângulo identificam o widget dele

O default de fieldName é Signature1 e aceita de 1 a 1024 bytes UTF-8; existingField exige um perfil incremental, um campo de assinaturas correspondente e um valor V ausente ou null

O bit read-only Ff 1 e flags de inteiros malformadas ou fora da faixa são rejeitados antes da preparação; dicionários herdados SV e Lock são resolvidos com PDF names semânticos únicos e traversal delimitado de pais

Valores de seeds e locks de campos

digestMethod seleciona o digest CMS real SHA256, SHA384 ou SHA512; SHA256 é o default, enquanto cades: true seleciona ETSI.CAdES.detached e inclui o atributo signing-certificate-v2 que vincula o certificado real de assinatura

reason, location e contactName são strings JSON UTF-8 gravadas como PDF text strings Unicode; razões obrigatórias de seeds comparam os valores Unicode delas, incluindo o valor especial de ponto único que exige uma razão omitida

Constraints SV obrigatórias checam o handler real, o SubFilter do CMS, a versão suportada de assinatura, o digest, a razão, a permissão de certificação, a atestação legal e o modo LockDocument; um timestamp obrigatório usa o transporte da aplicação e o workflow de confiança explícito descrito em Timestamps de assinatura no Windows, evidências obrigatórias de revogação assinada usam assinatura autenticada de CRL e OCSP, e aparências nomeadas obrigatórias usam presets reais gerados de aparências de assinaturas

Propriedades SVCert obrigatórias validam o certificado folha real do PFX e a cadeia de issuers incluída, bytes permitidos de certificados, OIDs de políticas de certificados, bits de key usage e atributos Unicode de subject DN antes de assinar

credentialSourceURL fornece proveniência asserida pela aplicação de credenciais para uma URL SVCert obrigatória; a biblioteca compara a URL declarada e o URLType suportado sem abrir aquele endpoint nem autenticar uma identidade de transporte

Locks de campos All, Include e Exclude são gravados como um dicionário indireto SigFieldLock e uma referência FieldMDP correspondente vinculada ao Catalog do documento; nomes de campos usam PDF text strings Unicode e permanecem criptografados em documentos criptografados

Um valor P assinado de Lock limita revisões posteriores usando a política original assinada de campos, independentemente de qualquer permissão DocMDP; segundas assinaturas permitidas preservam a revisão anterior exata e o CMS, enquanto um campo travado ou uma mudança P1 é rejeitada antes da publicação

O lookup de políticas decodifica escapes de PDF names exatamente uma vez, incluindo nomes Parent herdados; dicionários com nomes semânticos duplicados e pais inválidos ou cíclicos são rejeitados antes da publicação, enquanto nomes escapados válidos retêm os bytes de origem deles

contentsBytes tem default 16384 e aceita de 1024 a 1048576; reason, location e contactName preenchem o dicionário novo de assinaturas

Certificação e atestações legais

certificationPermission tem default 0 para assinatura de aprovação; 1, 2 ou 3 cria uma assinatura de certificação com a permissão DocMDP solicitada, vincula Perms DocMDP do Catalog ao dicionário indireto real de assinaturas, e retém qualquer transform FieldMDP independente

Certificação precisa ser a primeira assinatura, e um documento pode conter apenas uma assinatura de certificação; permissões malformadas de Catalog, referências não resolvidas e valores DocMDP sem binding de campo original assinado são rejeitados

legalAttestation é uma string Unicode opcional para assinatura de certificação e é gravada em Catalog Legal Attestation; uma lista SV LegalAttestation obrigatória precisa conter o texto selecionado, enquanto uma lista obrigatória vazia exige omissão

Assinaturas de certificação P2 e P3 existentes permitem assinatura de aprovação posterior quando os locks de campos e a política de revisões permitem; assinaturas P1 e campos travados rejeitam mudanças antes da publicação binária

Contrato da origem

O perfil incremental de jobs aceita uma origem original retida, incluindo PDFs criptografados suportados, e um grafo de objetos carregado não modificado; forneça password na operação sign para uma origem criptografada, separada de pfxPassword

A senha da origem autentica um snapshot raw independente, inicializa o contexto original de criptografia e reabre o candidato assinado; a revisão incremental resultante preserva o prefixo original de ciphertext, o dicionário de segurança e o document ID permanente

A descriptografia pode marcar internamente objetos como dirty ou remover um dicionário de segurança do grafo descriptografado; a operação compara esses estados e serializações delimitadas de objetos contra um baseline de origem recentemente autenticado, rejeitando mudanças reais de grafos e todos os estados de objetos gravados

Para uma senha de usuário, um campo de assinaturas existente exige permissão de form-fill ou anotações, e um widget novo de assinaturas exige permissão de anotações; uma senha de owner autenticada autoriza qualquer uma das operações, sujeita às políticas existentes de assinaturas

SaveLoadedDocumentToStream pode mudar o estado de serialização; ao assinar um grafo salvo ou editado, recarregue os bytes salvos num handle novo e assine aquela revisão

Mantenha o armazenamento da origem original estável pelo tempo de vida do handle; file jobs negam compartilhamento de gravação enquanto carregam e preparam o snapshot deles

O handle original retém as contagens de campos dele, identidade existente de campos, valores de formulários, bytes da origem e configurações anteriores de launch e decode; todo sucesso de assinatura retorna documentUpdated: false, e falhas de assinatura deixam o handle disponível para consultas, saving ou uma requisição válida posterior

File jobs rejeitam um path de saída que seja igual ou alias do arquivo de entrada, incluindo hard links; APIs diretas de streams rejeitam aliases reconhecíveis de streams e arquivos de origem, e os chamadores também devem manter o armazenamento de saída de callbacks opacos distinto do armazenamento de entrada

Preparação e validação

A operação copia os bytes raw da origem para um snapshot temporário criado exclusivamente, abre um clone incremental independente, anexa o placeholder por SaveIncrementalUpdate delimitado, e preenche o CMS desanexado pelo signer nativo de streams PFX

O PFX permanece aberto com compartilhamento de gravação negado desde o preflight de tamanho até a assinatura; arquivos temporários usam CREATE_NEW e são removidos apenas quando a operação é dona da criação deles

O candidato assinado precisa conter o prefixo exato de bytes da origem e as contagens esperadas de campos de formulários e assinaturas; a assinatura nova precisa verificar no campo selecionado dela, toda assinatura previamente preenchida ainda precisa verificar, e a análise de revisão de toda assinatura antiga precisa aceitar as constraints DocMDP, FieldMDP, usage-rights e identidade

Campos antigos não preenchidos são retidos sem serem contabilizados como preservedSignatures; assinaturas existentes malformadas, inválidas ou que violem a política causam rejeição antes da publicação binária

A verificação existente de assinaturas checa a integridade CMS contra os bytes assinados e a política nativa de revisões; quando timestamp é solicitado para a assinatura nova, a resposta dela valida separadamente a confiança explícita no TSA e as evidências configuradas de revogação antes da publicação

Orçamentos e publicação

O teto efetivo de saída é min(outputBytes, memoryBytes / 8) e inclui o prefixo da origem inteiro, objetos anexados, xref e reserva de assinatura; effectiveOutputLimit reporta o teto aplicado

O candidato não assinado e a saída assinada são delimitados separadamente por aquele teto, bytes PFX são limitados a memoryBytes / 8, e os orçamentos de decode de baseline de origem, clone e candidato são separadamente limitados a memoryBytes / 8, com thresholds de spilling em arquivos de no máximo 1 MiB

Estes são orçamentos de operações e buffers, e não uma garantia estrita de RSS do processo; criptografia, metadados de objetos, análise de revisões e a origem já carregada do chamador podem exigir memória residente adicional

Checagens de cancelamento e tempo decorrido se aplicam à cópia da origem, serialização e cópia do delta, leituras do candidato, leituras de verificação de assinaturas, leituras de análise de revisões e publicação por callbacks; falhas nativas sticky de streams retêm a categoria delas de orçamento ou cancelamento na fronteira do job

A saída binária é preparada e validada antes do primeiro callback de saída, e o tamanho do JSON de resultado é checado antes da publicação binária; a saída de callbacks em si não é atômica, então um callback binário ou de resultado com falha pode deixar bytes que o chamador deve descartar

File jobs gravam num candidato próprio no mesmo diretório, fazem flush dele, fecham os handles de origem e saída, e substituem atomicamente um alvo distinto após validação bem-sucedida; falhas preservam um destino existente

Sucesso retorna mediaType: application/pdf, fieldName, profile, incremental, existingField, certificationPermission, revocationInfo, appearanceProfile, preservedSignatures, effectiveOutputLimit, outputBytes e documentUpdated: false

Aceitação de replay

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

O runner descobre o RAD Studio pelo RootDir do registry dele, aceita overrides RADStudioRoot e PythonExecutable, e usa o toolchain FPC configurado quando CheckFPC é selecionado; FPCOnly reproduz apenas aqueles alvos nativos, enquanto OpenSSLWin32Library e OpenSSLWin64Library selecionam bibliotecas de runtime correspondentes para cada arquitetura

O runner não GUI checa ambas as APIs nativas Win32 e Win64 e as DLLs reais da C ABI usando callbacks parciais, campos vazios existentes, assinaturas anteriores, valores obrigatórios de seeds, CAdES real SHA384 e SHA512, metadados Unicode, segundas assinaturas permitidas e travadas, propriedades reais de certificados PFX, transforms AES-128 e AES-256 de field locks, restrições de permissões e credenciais de owner, senhas incorretas, grafos descriptografados dirty, snapshots exatos de origens criptografadas, recuperação de writers criptografados in-place, fixtures reais de CMS DocMDP P1 e P2, orçamentos, cancelamento, falhas de callbacks e reutilização da origem após falhas

Checagens independentes de pypdf, MuPDF e OpenSSL provam prefixos anteriores e faixas de bytes exatos, criptografia inalterada e IDs permanentes, texto original pesquisável, valores CMS antigos e novos válidos, a exceção de criptografia de Contents de assinaturas, e a rejeição de conteúdo assinado modificado; independent-proof.json registra as faixas de bytes e os resultados das provas

Tópicos relacionados

Operações de documentos, CopyLoadedSourceToStream, SaveIncrementalUpdate, EHPDFIncrementalOutputBudget