bacen / pix-api

API Pix: a API do Arranjo de Pagamentos Instantâneos Brasileiro, Pix, criado pelo Banco Central do Brasil.
https://bacen.github.io/pix-api
2.29k stars 260 forks source link

Cadeia de certificados no JWK Set #202

Open cryptographix opened 3 years ago

cryptographix commented 3 years ago

Olá, temos uma dúvida sobre o conteúdo do arquivo JWK Set do PSP, especificamente, se deve ou não constar o certificado raiz da cadeia de assinatura.

Por um lado, entende-se que o certificado raiz não deveria constar pelos seguintes motivos:

  1. O lado pagador tem a obrigação de validar que o certificado é emitido por uma AC amplamente conhecida
  2. Em consequência disso, o lado pagador deve ter uma lista de raizes confiáveis previamente estabelecida
  3. Faz parte das melhoras práticas, e também é bom senso, não incluir o certificado raiz em assinaturas digitais, como por exemplo, cadeias retornadas em conexões TLS.

Por outro lado, o exemplo do Appendix B do RFC 7515, citado no Manual de Segurança PIX 3.1, contém o certificado raiz.

O problema de incluir a raiz é justamente que facilita uso em configurações inseguras que não validam que a raiz é de uma AC "confiável", ou mais comum, que tem algum bug nesta validação. Não incluir a raiz, e principalmente não exigir a presença da raiz, é uma questão de criar um eco-sistema mais robusto a meu ver.

Por favor, esclarece qual a regra para PIX, se deve-se seguir ipsis-litteris o RFC, mesmo contrariando as "melhoras práticas"?

Ainda, por favor esclarece se um PSP pagador deveria recusar o payload assinado se o JWK Set referenciado não contém o certificado raiz?

rubenskuhl commented 3 years ago

Eu não vejo problema em o certificado raiz também estar contido na resposta, e já acessei vários sites que tinham toda a cadeia de certificação enviada. Lembrar que certificado é uma chave pública.

Só não pode ser confiado meramente por estar na resposta; a confiança nessa raiz precisa advir de outro fator, como a presença nas certificate stores de browsers e sistemas operacionais como Mozilla, Microsoft etc.

cryptographix commented 3 years ago

Eu não vejo problema em o certificado raiz também estar contido na resposta, e já acessei vários sites que tinham toda a cadeia de certificação enviada. Lembrar que certificado é uma chave pública.

Claro, por essa ótica não há problema. Um software bem feito e sem bug não terá nenhum problema com isso. No entanto, na prática ..

Temos três possibilidades para a regra:

  1. É proibida incluir a raiz
  2. Pode-se incluir a raiz mas esta não deve ser utilizada, unicamente, para a validação (uma vez que tem uma lista de certificados ativos)
  3. Inclusão da raiz é obrigatória (como temos visto com alguns PSP Pagadores ... )

Ai, opção 2 seria a mais adequada - pode incluir mas ninguém deve usar.

Só não pode ser confiado meramente por estar na resposta; a confiança nessa raiz precisa advir de outro fator, como a presença nas certificate stores de browsers e sistemas operacionais como Mozilla, Microsoft etc.

Suscita a pergunta - porque incluir na resposta kkk

Falando sério, eis o problema. Se a regra diz que "certificado de assinatura" deve ser emitido por uma AC amplamente conhecida, entende-se que, de tudo efeito, a raiz é desnecessária no JWK Set, sendo que a sua presença é apenas um agravante e poderá dar margem para erros de implementação. E pode crer, alguém vai implementar de jeito errado, e não vai ter caso de teste para detectar o caso. -> ecossistema mais frágil ..

Se por outro lado, o certificado de assinatura poderá ser "self-signed", aí valeria a pena incluí-lo, mas isso não é o caso.

rubenskuhl commented 3 years ago

Me parece que a presença da raiz tanto é prevista como possibilidade em norma técnica quanto deveria ser encarada dentro do https://en.wikipedia.org/wiki/Robustness_principle como algo que poderia ser aceito dentro da liberalidade, dado que não compromete a possibilidade de validação segundo a regra. Então os PSPs recebedores não deveriam incluir, mas se incluírem, isso não ser bloqueado pelos PSPs pagadores.

Agora, a exigência me parece sim despropositada. E imagino que você esteja falando de experiência de PSPs que o estejam requerindo... e isso adiciona-se aos problemas de interoperabilidade do Pix.

dmkamers commented 3 years ago

As ponderações sao validas, mas a regra esta clara do Manual de Segurança: a raiz deve estar presente. E a regra eh absolutamente clara ha décadas para validação de cadeias de confiança. Uma raiz NUNCA eh automaticamente aceita como confiável. Compreendo as preocupações, mas ponderar a respeito disso agora pode passar a impressão de que existe alguma possibilidade de fazer (ou nao) dessa ou daquela forma... (MINHA opinião: nao incluiria a raiz, mas isso eh absolutamente irrelevante no momento) Quem esta fazendo errado vai pagar o preço, eventualmente, porque ha razoes claras para nao confiar em uma raiz enviada por um terceiro.

Posso complementar com o seguinte alerta: o efeito do erro (confiar na raiz encaminhada, caso nao devesse) aqui significará ausência de integridade e não-repudio da cobrança (com grande probabilidade, dado que o TLS nao vai necessariamente assegurar isso por si). O cliente que assumir este risco e' que vai eventualmente pagar o preço. Nao me parece afetar a interoperabilidade (justamente por ser exigido).

dmkamers commented 3 years ago

Falando sério, eis o problema. Se a regra diz que "certificado de assinatura" deve ser emitido por uma AC amplamente conhecida, entende-se que, de tudo efeito, a raiz é desnecessária no JWK Set, sendo que a sua presença é apenas um agravante e poderá dar margem para erros de implementação. E pode crer, alguém vai implementar de jeito errado, e não vai ter caso de teste para detectar o caso. -> ecossistema mais frágil ..

Sean, voce esta corretíssimo. A rigor, nem os certificados intermediários precisariam estar presentes. Mas o manual de segurança esta muito claro. Assim como o método correto de validação. E pelo menos neste caso quem fizer errado assume integralmente as consequências (assim como no caso de nao validar um CRC, por mais que isso seja absurdamente sacramentado em tecnologia).

cryptographix commented 3 years ago

Sean, voce esta corretíssimo. A rigor, nem os certificados intermediários precisariam estar presentes. Mas o manual de segurança esta muito claro. Assim como o método correto de validação. E pelo menos neste caso quem fizer errado assume integralmente as consequências (assim como no caso de nao validar um CRC, por mais que isso seja absurdamente sacramentado em tecnologia).

Obrigado pelas respostas, @dmkamers. Pelo retorno acima e no issue #202, ficou claro que a raiz é obrigatária, embora há divergências se a regra é clara pelo manual de segurança, uma vez que precisávamos abrir o RFC e decodificar os base-64 do exemplo para identificar a presença da raiz no JWK Set.

Deixo aqui então uma sugestão para que o BACEN reconsiderasse esse requisito, em prol de um ecossistema mais robusto, algo que entendo como sendo um dos principais valores do projeto PIX e do SFB.

cryptographix commented 3 years ago

Outra sugestão seria adicionar um texto ao manual explicitando a exigência da raiz no JWK Set.

Na página 23, onde diz "e a sua respectiva cadeia de certificação", adicionar ", incluindo, obrigatoriamente, o certificado raiz".

dmkamers commented 3 years ago

@SeanWykes nao gosto de reproduzir a documentação aqui, mas segue o trecho do Manual de Segurança. Podemos, sim, citar explicitamente raiz, mas a descrição abaixo nao deixa duvida disso. Explicar-se demais pode gerar confusão também. Aproveito o gancho pra dar um toque para a comunidade: validar a cadeia NAO significa procurar o NOME do emissor... parece engraçado ter que dizer isso, mas... espero que estejam fazendo direto... segundo a norma...

• “x5c” (X.509 Certificate Chain): certificado digital X.509 – incluindo a chave pública que corresponde à chave privada utilizada na assinatura digital – e sua respectiva cadeia de certificação. o Deve-se utilizar um array JSON com os certificados, começando com o certificado cuja chave privada correspondente foi utilizada na assinatura, seguido pelo certificados adicionais da cadeia, onde cada certificado subsequente tenha sido utilizado para emissão do certificado anterior, conforme exemplo do Appendix B da RFC 7515.

EDIT1: estou ansioso com a frase tenha sido utilizado para emissão do certificado anterior... acho que vale a pena grifar que os certificados são criptograficamente encadeados num processo rigorosamente definido, desde o certificado do titular ate a raiz (e esta, por fim, alem de tudo, tem que ser confiável para quem verifica, e nao porque o titular diz: caso contrario, todo o processo é simplesmente inútil). Concordo plenamente que é complexo, mas esta área nao admite interpretações livres. Sua preocupação é mais do que legitima, e as dificuldades reportadas, que ja tivemos conhecimento, corroboram isso.

dmkamers commented 3 years ago

Aproveitando ainda o topico:

Os parâmetros “x5t” e “kid” definidos no JWK Set devem corresponder aos parâmetros de mesmo nome que constam no cabeçalho JWS, permitindo que a aplicação cliente consiga identificar de maneira inequívoca o certificado e a chave pública a ser utilizada para verificar a assinatura digital do JWS.

E:

“x5t” (X.509 Certificate SHA-1 Thumbprint): thumbprint, codificado em Base64url, do certificado que corresponde à chave privada utilizada para assinatura do JWS.

Sugiro fortemente nao inferir nada do texto direto, sem seguir e compreender as RFCs de embasamento, especialmente por se tratar de integridade e segurança.