# `Isox.Xmldsig.Signer`
[🔗](https://github.com/RicardoSantos-99/isox/blob/v0.2.0/lib/isox/xmldsig/signer.ex#L1)

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.

# `reference_spec`

```elixir
@type reference_spec() ::
  {uri :: String.t() | nil, transforms :: [String.t()], binary()}
```

# `digest`

```elixir
@spec digest(binary()) :: binary()
```

# `issuer_and_serial`

```elixir
@spec issuer_and_serial(binary()) :: {String.t(), integer()}
```

Nome do emissor (DN, renderizado) e número de série do certificado DER dado.

# `key_info_xml`

```elixir
@spec key_info_xml(String.t(), binary()) :: binary()
```

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.

# `otp_certificate`
*macro* 

# `otp_certificate`
*macro* 

# `otp_tbs_certificate`
*macro* 

# `otp_tbs_certificate`
*macro* 

# `rsa_sign`

```elixir
@spec rsa_sign(binary(), binary()) :: binary()
```

# `sign`

```elixir
@spec sign(binary(), binary(), binary(), binary()) :: binary()
```

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.

# `sign_references`

```elixir
@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`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
