Resumen

  • RFC 8879 permite sustituir el mensaje Certificate de TLS 1.3 por CompressedCertificate cuando el receptor ha anunciado algoritmos aceptables. La oferta autoriza una forma de representación; no demuestra que el emisor la usó ni concede recursos sin límite.
  • uncompressed_length debe coincidir exactamente con el mensaje reconstruido, la salida no puede superar ese valor y el receptor puede imponer un máximo inferior al techo de 24 bits de TLS. Todo ello ocurre antes de que el certificado pueda autenticar al peer.
  • Descomprimir con éxito no equivale a validar. La evidencia debe separar oferta, algoritmo elegido, bytes comprimidos, longitud declarada y real, hash reconstruido, cadena analizada, resultado de confianza, alerta, fallback y resultado de transporte.

La primera autorización fue de recursos

Imaginemos un terminador que procesa miles de handshakes nuevos. El cliente ha anunciado zlib, Brotli y Zstandard en compress_certificate. El servidor envía una carga pequeña, marca Brotli y declara que el Certificate original medía doce megabytes.

La identidad que podría justificar confianza permanece dentro del contenido. El cliente no puede usarla para decidir la asignación inicial. Primero comprueba que ofreció el algoritmo, compara la declaración con su límite local, impide que el decoder produzca más bytes y exige que la longitud final sea idéntica a la anunciada.

Ese orden convierte una función de rendimiento en una superficie de control. El emisor decide qué representación usar dentro de la lista recibida. El receptor conserva la autoridad sobre los transforms que ejecuta y el trabajo que una conexión no autenticada puede exigir. Anunciar Brotli no es firmar un cheque de memoria.

El framing admite hasta 16.777.215 bytes, pero RFC 8879 permite límites menores. La misma frontera debe regir Certificate comprimido y ordinario. Si una cadena sería demasiado grande en claro, envolverla en una carga pequeña no debe abrir una ruta alternativa hacia el parser.

Ofrecer no significa usar

La extensión es unidireccional. El cliente la coloca en ClientHello para indicar cómo puede descomprimir el certificado del servidor. El servidor la coloca en CertificateRequest para indicar cómo puede recibir el certificado del cliente. No existe una extensión de respuesta que confirme la selección.

El sender puede escoger un algoritmo ofrecido o enviar Certificate sin comprimir. Una captura con compress_certificate prueba capacidad receptora, no ejecución posterior. Un contador de ofertas no es un contador de mensajes comprimidos; uno de mensajes comprimidos tampoco prueba que la reconstrucción o la validación terminaran bien.

La dirección también es independiente. Que el cliente acepte certificados de servidor comprimidos no implica que pueda comprimir el suyo. Para eso hace falta la oferta del servidor en CertificateRequest. Builds y configuraciones pueden habilitar solo recepción, solo envío o conjuntos de algoritmos distintos.

RFC 8879 se aplica a TLS 1.3 y posteriores. Con TLS 1.2 la extensión se ignora. No es la compresión general de records que expuso CRIME. Aquí cambia la representación de un mensaje del handshake y, una vez reconstruido, vuelve a regir el procesamiento normal.

La entrada es el mensaje Certificate exacto

El compresor recibe el mensaje Certificate codificado que habría viajado sin esta extensión: contexto, lista de certificados y extensiones de cada entrada. No comprime certificados X.509 sueltos para montar después una versión aproximadamente equivalente.

Por eso la custodia necesita dos hashes. El primero identifica header, algoritmo y payload comprimido. El segundo identifica los bytes exactos del Certificate reconstruido. Las huellas del leaf y de los intermediarios describen después los objetos que la validación interpretó. Cada capa responde a una pregunta distinta.

Dos algoritmos generan representaciones diferentes a partir de la misma entrada. Una actualización de biblioteca también puede modificar los bytes comprimidos conservando idéntica salida. El hash del payload por sí solo no permite comparar la identidad lógica entre zlib, Brotli, Zstandard y la ruta sin compresión.

La precompresión exige la misma disciplina. OpenSSL permite guardar representaciones de certificados de servidor, mientras comprime los de cliente bajo demanda porque incluyen el contexto único enviado por el servidor. El cache del servidor debe vincularse al Certificate completo: renovar la cadena, cambiar un intermediate o alterar una extensión invalida el artefacto aunque el nombre del leaf siga igual.

La longitud declarada es una compuerta

CompressedCertificate porta ID de algoritmo, uncompressed_length y bytes comprimidos. Si el decoder falla, produce más de lo permitido o termina con otra longitud, el receptor aborta con bad_certificate. La aplicación no debe esperar al final para descubrir que una salida ya cruzó la frontera.

La declaración ayuda a rechazar temprano, pero no certifica buena fe ni seguridad semántica. Un valor legal para el protocolo puede ser inaceptable bajo alta concurrencia. El límite local debe traducir capacidad real de memoria y CPU en una regla aplicable antes del trabajo costoso.

La compresión tampoco garantiza reducción. Los tests de BoringSSL incluyen algoritmos de ensayo que encogen, expanden y producen contenido aleatorio. La propiedad de protocolo es reconstruir exactamente dentro de la cota; que el resultado transmitido sea menor es una meta de operación.

El ratio no basta para evaluar riesgo ni servicio. Hay que observar salida declarada y real, pico de asignación, tiempo de decoder y clase de fallo. Una gran reducción puede multiplicar el costo por conexión; una reducción pequeña puede ahorrar un paquete decisivo. Ninguna conclusión cabe en un porcentaje aislado.

La verificación comienza después de reconstruir

El Certificate obtenido debe procesarse como si hubiera llegado sin compresión. Se parsea la lista, se valida la cadena, se comprueban nombres y fechas, se aplica la política local y se verifica CertificateVerify en el transcript TLS 1.3. Un codec no corrige una CA desconocida ni una firma errónea.

Conviene mantener las causas separadas. Algoritmo no ofrecido: negociación. Output excesivo, decoder inválido o longitud distinta: reconstrucción. Estructura TLS malformada: parsing. Certificado vencido o nombre incorrecto: validación. CertificateVerify fallido: autenticación del handshake.

Si toda esa información se resume como certificate_error, desaparece la autoridad que tomó cada decisión. Si, en cambio, decompression_success se presenta como éxito de seguridad, se afirma demasiado: aún faltan identidad, posesión de clave y autorización de aplicación.

El running code muestra el recorrido. BoringSSL construye primero Certificate, guarda su tamaño, llama al callback seleccionado y serializa CompressedCertificate; sus pruebas ejercitan mismatches y transforms anómalos. OpenSSL ofrece controles separados para enviar, recibir, elegir preferencia y precomprimir. Registro, código y configuración desplegada no son el mismo hecho.

Medir el efecto completo

Las cadenas pueden dominar los bytes del primer handshake. Reducirlas puede ahorrar paquetes o un round trip, pero depende de cadena, congestion window, pérdida, CPU, cache y algoritmo común. El tamaño en disco de un PEM no es la medición adecuada; interesa el Certificate codificado que habría cruzado la conexión.

Registrar oferta y dirección, algoritmo real, tamaños, records, paquetes, retransmisiones, CPU, memoria, validación y tiempo total. Comparar con un control que usa la misma identidad y la misma política sin compresión. Solo así puede atribuirse una mejora.

Cuando no hay algoritmo común, Certificate ordinario es el fallback previsto. Su aumento puede reflejar un cambio de clientes, una biblioteca compilada sin codec o una nueva capa de terminación. Debe mantener las mismas reglas y el mismo límite de salida para ser un cambio de representación, no un downgrade de seguridad.

Fuentes