Alguém lhe diz que o seu site é inseguro. Abre-o: cadeado, sem aviso, certificado válido por mais quatro meses. Pede para tentar novamente e continua a falhar, numa rede a que não consegue aceder, num cliente que não tem.

Nenhum de vocês está errado, e o certificado não é o problema. O que difere é tudo aquilo que está por baixo.

Um certificado não é fidedigno por si só

O seu certificado não afirma que é fidedigno. É assinado por um certificado intermediário, que é assinado por uma raiz, e apenas a raiz está no armazenamento de confiança do visitante. O trabalho no momento da ligação é construir esse caminho, e o trabalho do seu servidor é enviar a parte do meio.

O TLS 1.3 descreve o que o servidor envia, e a redação merece ser lida:

certificate_list: Uma sequência (cadeia) de estruturas CertificateEntry, cada uma contendo um único certificado e conjunto de extensões.

E depois a regra que é normalmente ignorada:

O certificado do remetente DEVE estar na primeira CertificateEntry da lista. Cada certificado seguinte DEVE certificar diretamente o que o precede imediatamente. Porque a validação de certificados requer que as âncoras de confiança sejam distribuídas independentemente, um certificado que especifica uma âncora de confiança PODE ser omitido da cadeia, desde que os pares suportados sejam conhecidos por possuírem quaisquer certificados omitidos.

Leia a última frase com cuidado. A âncora de confiança, ou seja, a raiz, pode ser omitida, porque os clientes já a possuem. Nada aí justifica omitir o certificado intermediário. O seu servidor é suposto enviar tudo entre o seu certificado e a raiz, e um intermediário é precisamente isso.

A má configuração que nunca conseguirá ver

Omitir o certificado intermediário não produz um site meio funcional. Produz um site que funciona perfeitamente para si e falha para outras pessoas, o que é uma consequência consideravelmente mais cara.

A Mozilla descreveu a não especificação de certificados CA intermediários apropriados como “um dos problemas mais comuns de configuração de servidor”, e tomou medidas: o Firefox pré-carrega certificados CA intermediários antecipadamente, numa lista que “contém mais de duas mil entradas”, especificamente para reduzir “erros de emissor desconhecido no handshake TLS”.

Pense bem no que isto significa. Os navegadores ativamente compensam este erro. Um navegador que já possua o intermediário completa a ligação quer o seu servidor o tenha enviado quer não, por isso o seu próprio teste passa e a má configuração permanece invisível. A compensação é uma boa engenharia e é também a razão pela qual ninguém repara.

Por que um cliente falha onde outro tem sucesso

Existe um segundo mecanismo que o mascara, e vem do certificado em si.

Um certificado pode indicar onde se pode encontrar o certificado do seu emissor. O RFC 5280 define esse campo, e é cuidadoso sobre o que é:

o OID id-ad-caIssuers é utilizado quando a informação adicional lista certificados que foram emitidos para a CA que emitiu o certificado contendo esta extensão. A descrição de emissores CA referenciada destina-se a ajudar utilizadores de certificados na seleção de um caminho de certificação.

“Destina-se a ajudar” é a frase-chave. É um apontador, não uma obrigação. Um cliente pode segui-lo e obter a peça em falta, e um cliente pode recusar. Ambos estão em conformidade.

A especificação TLS é igualmente clara sobre o estado do mundo, notando que os servidores às vezes enviam certificados adicionais ou fora de ordem e que “outros são simplesmente configurados incorretamente”, antes de pedir às implementações que sejam tolerantes com isto.

O que usou para testar
Um navegador desktop atual, que pré-carrega milhares de intermediários e buscará um emissor em falta se tiver de o fazer. O cliente mais tolerante que possui
O que o seu visitante usou
Algo mais rigoroso ou mais antigo, que valida apenas o que lhe foi entregue e relata um emissor desconhecido quando a cadeia não atinge uma raiz

Portanto, a tolerância é uma decisão do cliente e não uma propriedade da sua configuração, e tem estado a testar com o cliente mais provável de o perdoar.

Os relatórios que isto realmente gera

Porque os clientes tolerantes são os navegadores, as falhas aparecem noutro lugar, e raramente chegam descritas como um problema de certificado.

  • Um webhook deixa de ser entregue. O servidor de outra pessoa é agora o cliente, e não tem lista pré-carregada nem interesse em buscar o seu emissor.
  • Uma aplicação móvel não consegue iniciar sessão enquanto a mesma conta funciona na web, porque a pilha de rede da aplicação não é o navegador do sistema.
  • Uma integração de pagamento ou envio falha contra o seu URL de retorno, normalmente com uma mensagem sobre um emissor desconhecido ou não fidedigno.
  • Um escritório ou um dispositivo mais antigo não consegue alcançar o site, e toda a gente consegue.

Nenhum deles soa como “a cadeia de certificados está incompleta”, o que é a razão pela qual as horas vão para o lugar errado primeiro.

O intermediário é a unidade de raio de impacto

Uma razão mais para saber qual intermediário você depende, separadamente de se o envia.

Um intermediário assina muitos certificados. Se um for revogado, desconfiado ou permitido expirar, cada certificado sob o mesmo deixa de validar no mesmo momento. O seu certificado pode estar a meses da sua própria expiração, inalterado, e mesmo assim falhar, porque o que quebrou é uma ligação acima e nunca foi seu.

A maioria da monitorização de certificados observa uma única data: quando o seu próprio certificado expira. Essa é a data correta a observar e não é a única, e a outra pertence a um certificado que não escolheu e provavelmente não consegue nomear.

Verificar isto leva cerca de trinta segundos

Pergunte ao servidor o que realmente envia, a partir de algo que não é o seu navegador:

openssl s_client -showcerts -connect example.com:443 -servername example.com </dev/null

Duas coisas a ler no resultado. Conte os certificados: uma cadeia pública típica entrega o seu certificado e pelo menos um intermediário, portanto exatamente um certificado é o sintoma clássico desta falha. Depois leia o issuer do seu próprio certificado e verifique que um certificado com esse subject está presente mais abaixo.

Session Replay

Extensão Chrome gratuita. Um clique na página que está com mau funcionamento captura a imagem de ecrã, a consola e o registo de rede, e oferece-lhe uma ligação para colar no bilhete.

Obtenha a extensão

Se o que lhe chega é uma captura de ecrã de uma página de aviso, as cinco falhas diferentes por trás dessa página merecem ser separadas antes de começar: a sua ligação não é privada.

O que deve aprender com isto

Um certificado é uma ligação, não uma credencial. É fidedigno porque um caminho pode ser construído a partir dele para algo que o visitante já confia, e o seu servidor é responsável pelo meio desse caminho.

O modo de falha é invulgarmente cruel porque a compensação é tão boa. Os navegadores pré-carregam milhares de intermediários e perseguem um emissor em falta, por isso o cliente que testa é o menos provável de o informar. Os que o fazem são webhooks, aplicações móveis e integrações de pagamento, e informam-no em palavras que nunca mencionam certificados.

As especificações são RFC 8446 para o que um servidor deve enviar e RFC 5280 para o campo que nomeia a localização de um emissor.