Resumo

  • EOF informa que o transporte acabou, não que chegou tudo o que o par pretendia enviar. O close_notify acrescenta uma declaração protegida de que não haverá mais mensagens TLS naquele sentido.
  • Desde o TLS 1.3, fechar o sentido de escrita não obriga o descarte imediato do tráfego inverso. A completude de HTTP continua dependendo de comprimento, terminadores e marcadores de fluxo próprios da aplicação.

Um prefixo íntegro ainda pode ser apenas um prefixo

Há uma falha particularmente traiçoeira: todos os registros TLS recebidos passam pela autenticação, a aplicação obtém bytes plausíveis e então o socket devolve EOF. Nada do que chegou foi adulterado. Ainda assim, talvez faltasse uma cauda que nunca atravessou a conexão.

Quando a mensagem anuncia seu próprio tamanho, a ausência aparece. Faltam quatro octetos para o Content-Length, ou não chega o bloco final de uma codificação em chunks. Quando o próprio fechamento delimita a resposta, porém, um final legítimo e uma interrupção prematura podem produzir a mesma sequência observável.

O TLS 1.0 tratou essa ambiguidade como risco de truncamento. Sua solução foi o alerta close_notify: o emissor declara, dentro da sequência protegida, que não enviará mais mensagens naquela conexão. Qualquer registro posterior ao alerta deve ser ignorado.

Essa declaração tem escopo deliberadamente estreito. O TLS pode atestar o encerramento de seus registros; não conhece o fim de uma notícia, de um download, de uma resposta HTTP ou de uma transação. A aplicação ainda precisa provar que os registros contêm uma unidade completa.

O primeiro TLS vinculou o fechamento à retomada

O desenho original aplicava uma sanção duradoura. Se a conexão TLS 1.0 terminasse sem a troca correta dos alertas, a sessão não poderia ser retomada. Uma terminação sem prova retirava do par a possibilidade de reutilizar aquele estado criptográfico numa conexão seguinte.

A prática de implementação enfraqueceu esse vínculo. O TLS 1.2 registra que a versão 1.1 já havia removido a proibição automática de retomada para acompanhar o comportamento difundido. Continuava sendo obrigatório enviar close_notify, mas a falta do alerta, sozinha, deixava de condenar o estado da sessão futura.

A mudança preservou o significado sem insistir numa punição que o ecossistema não sustentava. Saber como uma conexão terminou e decidir se uma associação anterior pode ser retomada são questões próximas, mas não idênticas.

O reflexo simétrico podia truncar a resposta

Nas versões anteriores ao TLS 1.3, receber close_notify acionava uma obrigação imediata: responder com o próprio alerta, fechar a conexão e descartar escritas pendentes. O ritual pressupunha que os dois sentidos deveriam terminar juntos.

Aplicações reais não obedecem sempre a essa simetria. Um cliente pode ter terminado de enviar a requisição e ainda aguardar a resposta. Se o servidor recebe o primeiro alerta e elimina dados que ainda pretendia transmitir, o mecanismo contra truncamento passa a truncar o sentido inverso.

O TLS 1.3 redesenhou essa fronteira. close_notify encerra ordenadamente um único sentido: fecha a escrita do emissor, não sua leitura. Quem recebe não precisa responder de imediato nem abandonar dados pendentes. Cada lado pode completar sua produção quando a aplicação estiver pronta.

O texto também localiza com precisão o que permanece incerto. Se o transporte fecha antes de close_notify, o receptor não sabe se recebeu todos os dados enviados pelo par. Os registros já autenticados não se tornam inseguros retroativamente; a dúvida está no futuro invisível que talvez existisse após o último registro observado.

O HTTP fornece a régua que falta ao TLS

O antigo HTTP sobre TLS já separava integridade do prefixo e completude da mensagem. Um fechamento prematuro não corrompe o que foi autenticado, mas pode esconder dados posteriores. Como o TLS não enxerga os limites de requisições e respostas HTTP, cabe ao cliente consultar o enquadramento do protocolo.

A especificação atual de HTTP/1.1 mantém a divisão. Uma resposta com Content-Length termina quando chegam exatamente os octetos declarados; uma resposta em chunks precisa do chunk final de tamanho zero. Sem esses limites, a mensagem é incompleta. Se a resposta só termina com o fechamento, a ausência de um alerta TLS válido impede tratar o prefixo como completo com segurança.

No HTTP/2, a separação aparece em escala menor. O END_STREAM de RFC 9113 encerra um sentido de um fluxo HTTP, enquanto outros fluxos continuam na mesma conexão. Final de fluxo e final de TLS são acontecimentos diferentes, cada um com sua evidência.

Uma mensagem protegida, uma afirmação limitada

close_notify não confirma a identidade humana, não autoriza uma operação, não garante que a aplicação processou os bytes e não certifica sozinho a completude de uma mensagem superior. Ele afirma apenas que o emissor não enviará outras mensagens TLS naquele sentido.

EOF é um evento do transporte. O alerta é prova protegida sobre intenção de envio. Comprimento, chunk final ou END_STREAM são prova estrutural da aplicação. Sistemas confiáveis não transformam essas três observações em um único sinal genérico de sucesso.

Fontes e limites

Esta análise usa RFC 2246, RFC 2818, RFC 5246, RFC 8446, RFC 9112 e RFC 9113. Os documentos sustentam as regras e sua evolução, mas não medem padrões atuais de bibliotecas, adoção em produção nem a causa de um alerta ausente num incidente específico.