Núcleo do XMLDSig do Pix (Manual de Segurança do SFN Vol. II §3), comum
aos dois perfis que o manual define: SPI, com três <ds:Reference>
(tabela 3), e DICT, com duas (tabela 4). Hoje só o perfil SPI está
implementado, em sign/4. sign_references/3 e key_info_xml/2 já
bastam para montar o do DICT quando existir um simulador para ele, já
que a diferença entre os dois é só a lista de referências, não o resto
do mecanismo (§3.2 do manual: os passos são os mesmos).
RSA-SHA256, digest SHA-256, canonicalização exclusiva.
Summary
Functions
Nome do emissor (DN, renderizado) e número de série do certificado DER dado.
Monta <ds:KeyInfo> com <ds:X509IssuerSerial> (tabela 2, item 1.2.3.1
do manual): nome do emissor (DN) e número de série do certificado, não
o certificado inteiro embutido. É assim que o manual descreve: quem
verifica é responsável por manter sua própria base de números de série
e chaves públicas dos certificados (§3.3, nota de rodapé), não por
confiar num certificado que veio dentro da própria mensagem.
Assina canonical_signed_info em RSA-SHA256 (PKCS#1 v1.5) e devolve o
valor em Base64, como vai em <ds:SignatureValue>. private_key_der
aceita os mesmos formatos de sign/4.
Perfil SPI (tabela 3): três <ds:Reference>, sendo KeyInfo por Id,
AppHdr sem <Sgntr> preenchido e com transformação
enveloped-signature, e Document sem atributo URI. A última fica fora
do processamento padrão de XMLDSig: "deve ser interpretada pela
aplicação de forma a referenciar a mensagem ISO 20.022 propriamente
dita", manual §3.1.
Monta <ds:Signature> a partir de uma lista arbitrária de referências
já canônicas, o núcleo comum aos dois perfis do manual. key_info_xml
entra pronto (já contém o Id que a referência correspondente usa em
URI="#...") porque quem monta a lista de referências é quem sabe qual
delas aponta pro KeyInfo.
Types
Functions
Nome do emissor (DN, renderizado) e número de série do certificado DER dado.
Monta <ds:KeyInfo> com <ds:X509IssuerSerial> (tabela 2, item 1.2.3.1
do manual): nome do emissor (DN) e número de série do certificado, não
o certificado inteiro embutido. É assim que o manual descreve: quem
verifica é responsável por manter sua própria base de números de série
e chaves públicas dos certificados (§3.3, nota de rodapé), não por
confiar num certificado que veio dentro da própria mensagem.
Assina canonical_signed_info em RSA-SHA256 (PKCS#1 v1.5) e devolve o
valor em Base64, como vai em <ds:SignatureValue>. private_key_der
aceita os mesmos formatos de sign/4.
Perfil SPI (tabela 3): três <ds:Reference>, sendo KeyInfo por Id,
AppHdr sem <Sgntr> preenchido e com transformação
enveloped-signature, e Document sem atributo URI. A última fica fora
do processamento padrão de XMLDSig: "deve ser interpretada pela
aplicação de forma a referenciar a mensagem ISO 20.022 propriamente
dita", manual §3.1.
app_hdr_xml e document_xml precisam já vir em forma canônica
exclusiva. Quem chama é o caminho de template da lib de codec (ADR
0006), e essa é a razão de ele existir: sem isso, assinar pagaria
canonicalização no caminho quente.
Passar XML não canônico aqui produz uma assinatura que não bate na verificação, porque a verificação sempre canonicaliza de verdade (não pode confiar no que chegou de terceiro). Isto não é checado aqui de propósito: checar seria fazer a mesma canonicalização que o caminho de template existe para evitar.
private_key_der é a chave privada RSA em DER, em um de dois formatos:
PKCS#1 (RSAPrivateKey, o PEM BEGIN RSA PRIVATE KEY) ou PKCS#8 sem
cifra (PrivateKeyInfo, o PEM BEGIN PRIVATE KEY, que é o que o
OpenSSL 3 grava por padrão e o que vem dentro de um .pfx/.p12).
Chave de outro algoritmo, como EC, levanta ArgumentError, porque o
perfil é RSA-SHA256. certificate_der é o certificado X.509 dessa
chave, também em DER.
@spec sign_references([reference_spec()], binary(), binary()) :: binary()
Monta <ds:Signature> a partir de uma lista arbitrária de referências
já canônicas, o núcleo comum aos dois perfis do manual. key_info_xml
entra pronto (já contém o Id que a referência correspondente usa em
URI="#...") porque quem monta a lista de referências é quem sabe qual
delas aponta pro KeyInfo.
private_key_der aceita os mesmos formatos de sign/4: RSA em DER,
PKCS#1 ou PKCS#8 sem cifra.