static int ssl_print_random(BIO *bio, int indent, const unsigned char **pmsg, size_t *pmsglen) { unsigned int tm; const unsigned char *p = *pmsg; if (*pmsglen < 32) return 0; tm = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; p += 4; BIO_indent(bio, indent, 80); BIO_puts(bio, "Random:\n"); BIO_indent(bio, indent + 2, 80); BIO_printf(bio, "gmt_unix_time=0x%08X\n", tm); ssl_print_hex(bio, indent + 2, "random_bytes", p, 28); *pmsg += 32; *pmsglen -= 32; return 1; }
static int ssl_print_hexbuf(BIO *bio, int indent, const char *name, size_t nlen, const unsigned char **pmsg, size_t *pmsglen) { size_t blen; const unsigned char *p = *pmsg; if (*pmsglen < nlen) return 0; blen = p[0]; if (nlen > 1) blen = (blen << 8)|p[1]; if (*pmsglen < nlen + blen) return 0; p += nlen; ssl_print_hex(bio, indent, name, p, blen); *pmsg += blen + nlen; *pmsglen -= blen + nlen; return 1; }
static int ssl_print_extension(BIO *bio, int indent, int server, int extype, const unsigned char *ext, size_t extlen) { size_t xlen; BIO_indent(bio, indent, 80); 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_ec_point_formats: if (extlen < 1) return 0; xlen = ext[0]; if (extlen != xlen + 1) return 0; return ssl_trace_list(bio, indent + 2, ext + 1, xlen, 1, ssl_point_tbl); case TLSEXT_TYPE_elliptic_curves: if (extlen < 2) return 0; xlen = (ext[0] << 8) | ext[1]; if (extlen != xlen + 2) return 0; return ssl_trace_list(bio, indent + 2, ext + 2, xlen, 2, ssl_curve_tbl); case TLSEXT_TYPE_signature_algorithms: if (extlen < 2) return 0; xlen = (ext[0] << 8) | ext[1]; if (extlen != xlen + 2) return 0; if (xlen & 1) return 0; ext += 2; while(xlen > 0) { BIO_indent(bio, indent + 2, 80); BIO_printf(bio, "%s+%s (%d+%d)\n", ssl_trace_str(ext[0], ssl_md_tbl), ssl_trace_str(ext[1], ssl_sig_tbl), ext[0], ext[1]); xlen-= 2; ext+= 2; } break; case TLSEXT_TYPE_renegotiate: if (extlen < 1) return 0; xlen = ext[0]; if (xlen + 1 != extlen) return 0; ext++; if (xlen) { if (server) { if (xlen & 1) return 0; xlen >>= 1; } ssl_print_hex(bio, indent + 4, "client_verify_data", ext, xlen); if (server) { ext += xlen; ssl_print_hex(bio, indent + 4, "server_verify_data", ext, xlen); } } else { BIO_indent(bio, indent + 4, 80); BIO_puts(bio, "<EMPTY>\n"); } break; case TLSEXT_TYPE_heartbeat: if (extlen != 1) return 0; BIO_indent(bio, indent + 2, 80); BIO_printf(bio, "HeartbeatMode: %s\n", ssl_trace_str(ext[0], ssl_hb_tbl)); break; case TLSEXT_TYPE_session_ticket: if (extlen != 0) ssl_print_hex(bio, indent + 4, "ticket", ext, extlen); break; default: BIO_dump_indent(bio, (char *)ext, extlen, indent + 2); }
static int ssl_print_extension(BIO *bio, int indent, int server, int extype, const unsigned char *ext, size_t extlen) { size_t xlen, share_len; BIO_indent(bio, indent, 80); 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_ec_point_formats: if (extlen < 1) return 0; xlen = ext[0]; if (extlen != xlen + 1) return 0; return ssl_trace_list(bio, indent + 2, ext + 1, xlen, 1, ssl_point_tbl); case TLSEXT_TYPE_supported_groups: if (extlen < 2) return 0; xlen = (ext[0] << 8) | ext[1]; if (extlen != xlen + 2) return 0; return ssl_trace_list(bio, indent + 2, ext + 2, xlen, 2, ssl_groups_tbl); case TLSEXT_TYPE_signature_algorithms: if (extlen < 2) return 0; xlen = (ext[0] << 8) | ext[1]; if (extlen != xlen + 2) return 0; if (xlen & 1) return 0; ext += 2; while (xlen > 0) { BIO_indent(bio, indent + 2, 80); BIO_printf(bio, "%s+%s (%d+%d)\n", ssl_trace_str(ext[0], ssl_md_tbl), ssl_trace_str(ext[1], ssl_sig_tbl), ext[0], ext[1]); xlen -= 2; ext += 2; } break; case TLSEXT_TYPE_renegotiate: if (extlen < 1) return 0; xlen = ext[0]; if (xlen + 1 != extlen) return 0; ext++; if (xlen) { if (server) { if (xlen & 1) return 0; xlen >>= 1; } ssl_print_hex(bio, indent + 4, "client_verify_data", ext, xlen); if (server) { ext += xlen; ssl_print_hex(bio, indent + 4, "server_verify_data", ext, xlen); } } else { BIO_indent(bio, indent + 4, 80); BIO_puts(bio, "<EMPTY>\n"); } break; case TLSEXT_TYPE_heartbeat: return 0; case TLSEXT_TYPE_session_ticket: if (extlen != 0) ssl_print_hex(bio, indent + 4, "ticket", ext, extlen); break; case TLSEXT_TYPE_key_share: if (extlen < 2) return 0; if (server) { xlen = extlen; } else { xlen = (ext[0] << 8) | ext[1]; if (extlen != xlen + 2) return 0; ext += 2; } for (; xlen > 0; ext += share_len, xlen -= share_len) { int group_id; if (xlen < 4) return 0; group_id = (ext[0] << 8) | ext[1]; share_len = (ext[2] << 8) | ext[3]; ext += 4; xlen -= 4; if (xlen < share_len) return 0; BIO_indent(bio, indent + 4, 80); BIO_printf(bio, "NamedGroup: %s\n", ssl_trace_str(group_id, ssl_groups_tbl)); ssl_print_hex(bio, indent + 4, "key_exchange: ", ext, share_len); } break; case TLSEXT_TYPE_supported_versions: 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_version_tbl); default: BIO_dump_indent(bio, (const char *)ext, extlen, indent + 2); }