{SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"},
{SSL3_MT_SUPPLEMENTAL_DATA, "SupplementalData"},
{SSL3_MT_KEY_UPDATE, "KeyUpdate"},
+ {SSL3_MT_COMPRESSED_CERTIFICATE, "CompressedCertificate"},
# ifndef OPENSSL_NO_NEXTPROTONEG
{SSL3_MT_NEXT_PROTO, "NextProto"},
# endif
{TLSEXT_TYPE_padding, "padding"},
{TLSEXT_TYPE_encrypt_then_mac, "encrypt_then_mac"},
{TLSEXT_TYPE_extended_master_secret, "extended_master_secret"},
+ {TLSEXT_TYPE_compress_certificate, "compress_certificate"},
{TLSEXT_TYPE_session_ticket, "session_ticket"},
{TLSEXT_TYPE_psk, "psk"},
{TLSEXT_TYPE_early_data, "early_data"},
{SSL_KEY_UPDATE_REQUESTED, "update_requested"}
};
+static const ssl_trace_tbl ssl_comp_cert_tbl[] = {
+ {TLSEXT_comp_cert_none, "none"},
+ {TLSEXT_comp_cert_zlib, "zlib"},
+ {TLSEXT_comp_cert_brotli, "brotli"},
+ {TLSEXT_comp_cert_zstd, "zstd"}
+};
+
static void ssl_print_hex(BIO *bio, int indent, const char *name,
const unsigned char *msg, size_t msglen)
{
BIO_printf(bio, "extension_type=%s(%d), length=%d\n",
ssl_trace_str(extype, ssl_exts_tbl), extype, (int)extlen);
switch (extype) {
+ case TLSEXT_TYPE_compress_certificate:
+ if (extlen < 1)
+ return 0;
+ xlen = ext[0];
+ if (extlen != xlen + 1)
+ return 0;
+ return ssl_trace_list(bio, indent + 2, ext + 1, xlen, 2, ssl_comp_cert_tbl);
+
case TLSEXT_TYPE_max_fragment_length:
if (extlen < 1)
return 0;
return 1;
}
+static int ssl_print_compressed_certificates(BIO *bio, const SSL_CONNECTION *sc,
+ int server, int indent,
+ const unsigned char *msg,
+ size_t msglen)
+{
+ size_t uclen;
+ size_t clen;
+ unsigned int alg;
+ int ret = 1;
+#ifndef OPENSSL_NO_COMP_ALG
+ COMP_METHOD *method;
+ COMP_CTX *comp = NULL;
+ unsigned char* ucdata = NULL;
+#endif
+
+ if (msglen < 8)
+ return 0;
+
+ alg = (msg[0] << 8) | msg[1];
+ uclen = (msg[2] << 16) | (msg[3] << 8) | msg[4];
+ clen = (msg[5] << 16) | (msg[6] << 8) | msg[7];
+ if (msglen != clen + 8)
+ return 0;
+
+ msg += 8;
+ BIO_indent(bio, indent, 80);
+ BIO_printf(bio, "Compression type=%s (0x%04x)\n", ssl_trace_str(alg, ssl_comp_cert_tbl), alg);
+ BIO_indent(bio, indent, 80);
+ BIO_printf(bio, "Uncompressed length=%d\n", (int)uclen);
+ BIO_indent(bio, indent, 80);
+ BIO_printf(bio, "Compressed length=%d, Ratio=%f:1\n", (int)clen, (float)uclen / (float)clen);
+
+ BIO_dump_indent(bio, (const char *)msg, clen, indent);
+
+#ifndef OPENSSL_NO_COMP_ALG
+ if (!ossl_comp_has_alg(alg))
+ return 0;
+
+ if ((ucdata = OPENSSL_malloc(uclen)) == NULL)
+ return 0;
+
+ switch (alg) {
+ case TLSEXT_comp_cert_zlib:
+ method = COMP_zlib();
+ break;
+ case TLSEXT_comp_cert_brotli:
+ method = COMP_brotli_oneshot();
+ break;
+ case TLSEXT_comp_cert_zstd:
+ method = COMP_zstd_oneshot();
+ break;
+ default:
+ goto err;
+ }
+
+ if ((comp = COMP_CTX_new(method)) == NULL
+ || COMP_expand_block(comp, ucdata, uclen, (unsigned char*)msg, clen) != (int)uclen)
+ goto err;
+
+ ret = ssl_print_certificates(bio, sc, server, indent, ucdata, uclen);
+ err:
+ COMP_CTX_free(comp);
+ OPENSSL_free(ucdata);
+#endif
+ return ret;
+}
+
static int ssl_print_cert_request(BIO *bio, int indent, const SSL_CONNECTION *sc,
const unsigned char *msg, size_t msglen)
{
return 0;
break;
+ case SSL3_MT_COMPRESSED_CERTIFICATE:
+ if (!ssl_print_compressed_certificates(bio, sc, server, indent + 2, msg, msglen))
+ return 0;
+ break;
+
case SSL3_MT_CERTIFICATE_VERIFY:
if (!ssl_print_signature(bio, indent + 2, sc, &msg, &msglen))
return 0;