Uso interno da biblioteca: não faz parte da API pública.
Assinatura XMLDSig envelopada, com C14N inclusiva, da DPS, do pedido de registro de evento e da NFS-e de decisão judicial.
Por que não há canonicalização aqui
O XMLDSig digere a forma canônica do que assina, não os bytes que vão pela rede. O OTP não traz
C14N, e as dependências da biblioteca também não. Então a biblioteca vai pelo outro caminho: o
escritor do leiaute (Nfse.Schema.Runtime.encode/4) já escreve na forma canônica, sem espaço
entre tags, sem <x/> e com o namespace só na raiz, e sign/4 digere os bytes literais. Para
essa forma, a C14N de uma subárvore é a própria subárvore, com uma exceção.
A exceção: o namespace herdado
A C14N inclusiva escreve no topo do que canonicaliza todo namespace em escopo. O infDPS herda
o namespace da NFS-e da DPS e não o declara, mas o digest é calculado sobre
<infDPS xmlns="http://www.sped.fazenda.gov.br/nfse" Id="DPS...">...Assinar o <infDPS Id="DPS..."> literal dá uma assinatura bem formada sobre os bytes errados,
e a Sefin responde só "assinatura inválida". Por isso sign/4 injeta o namespace antes de
digerir. Daí vem a exigência sobre a raiz: ela declara o namespace da NFS-e como padrão e nenhum
outro, porque cada namespace a mais que ela declarasse também entraria no topo da forma canônica.
A mesma regra vale um nível abaixo: o SignedInfo herda o namespace do XMLDSig da Signature,
então os bytes que o RSA assina levam um xmlns que os da rede não levam.
Onde a assinatura entra
A Signature devolvida vai logo depois do elemento assinado, como irmã dele dentro da raiz. Ela
fica fora da subárvore digerida, e a transformação enveloped-signature não tira nada dali.
Cada documento leva uma assinatura só. A NFS-e de decisão judicial carrega a DPS sem assinatura
própria (o Signature do TCDPS é opcional) e só o infNFSe é assinado: o digest dele cobre a
DPS embutida.
Summary
Functions
O algoritmo que a biblioteca usa quando o chamador não escolhe outro.
Assina element e devolve a <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> que vai
logo depois dele, como irmã dentro da raiz.
Types
Functions
@spec default_algorithm() :: algorithm()
O algoritmo que a biblioteca usa quando o chamador não escolhe outro.
É :rsa_sha1 até a conferência na produção restrita.
@spec sign(binary(), String.t(), Nfse.Certificate.t(), algorithm()) :: binary()
Assina element e devolve a <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> que vai
logo depois dele, como irmã dentro da raiz.
element são os bytes literais e canônicos do elemento, exatamente como vão aparecer no
documento final, e id é o valor do atributo Id dele, para onde a Reference aponta. A raiz
que recebe o elemento declara o namespace da NFS-e como padrão e nenhum outro.
Levanta ArgumentError quando element não está na forma que este módulo sabe digerir. É de
propósito: cada um desses casos daria uma assinatura de aparência válida sobre os bytes errados,
e o único retorno seria a recusa da Sefin, dias depois.