1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * Stolen from tjh's ssl/ssl_trc.c stuff. 12e1051a39Sopenharmony_ci */ 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ci#include <stdio.h> 15e1051a39Sopenharmony_ci#include "bio_local.h" 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#define DUMP_WIDTH 16 18e1051a39Sopenharmony_ci#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH - ((i - (i > 6 ? 6 : i) + 3) / 4)) 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_ci#define SPACE(buf, pos, n) (sizeof(buf) - (pos) > (n)) 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ciint BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), 23e1051a39Sopenharmony_ci void *u, const void *s, int len) 24e1051a39Sopenharmony_ci{ 25e1051a39Sopenharmony_ci return BIO_dump_indent_cb(cb, u, s, len, 0); 26e1051a39Sopenharmony_ci} 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ciint BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), 29e1051a39Sopenharmony_ci void *u, const void *v, int len, int indent) 30e1051a39Sopenharmony_ci{ 31e1051a39Sopenharmony_ci const unsigned char *s = v; 32e1051a39Sopenharmony_ci int res, ret = 0; 33e1051a39Sopenharmony_ci char buf[288 + 1]; 34e1051a39Sopenharmony_ci int i, j, rows, n; 35e1051a39Sopenharmony_ci unsigned char ch; 36e1051a39Sopenharmony_ci int dump_width; 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ci if (indent < 0) 39e1051a39Sopenharmony_ci indent = 0; 40e1051a39Sopenharmony_ci else if (indent > 64) 41e1051a39Sopenharmony_ci indent = 64; 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ci dump_width = DUMP_WIDTH_LESS_INDENT(indent); 44e1051a39Sopenharmony_ci rows = len / dump_width; 45e1051a39Sopenharmony_ci if ((rows * dump_width) < len) 46e1051a39Sopenharmony_ci rows++; 47e1051a39Sopenharmony_ci for (i = 0; i < rows; i++) { 48e1051a39Sopenharmony_ci n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "", 49e1051a39Sopenharmony_ci i * dump_width); 50e1051a39Sopenharmony_ci for (j = 0; j < dump_width; j++) { 51e1051a39Sopenharmony_ci if (SPACE(buf, n, 3)) { 52e1051a39Sopenharmony_ci if (((i * dump_width) + j) >= len) { 53e1051a39Sopenharmony_ci strcpy(buf + n, " "); 54e1051a39Sopenharmony_ci } else { 55e1051a39Sopenharmony_ci ch = *(s + i * dump_width + j) & 0xff; 56e1051a39Sopenharmony_ci BIO_snprintf(buf + n, 4, "%02x%c", ch, 57e1051a39Sopenharmony_ci j == 7 ? '-' : ' '); 58e1051a39Sopenharmony_ci } 59e1051a39Sopenharmony_ci n += 3; 60e1051a39Sopenharmony_ci } 61e1051a39Sopenharmony_ci } 62e1051a39Sopenharmony_ci if (SPACE(buf, n, 2)) { 63e1051a39Sopenharmony_ci strcpy(buf + n, " "); 64e1051a39Sopenharmony_ci n += 2; 65e1051a39Sopenharmony_ci } 66e1051a39Sopenharmony_ci for (j = 0; j < dump_width; j++) { 67e1051a39Sopenharmony_ci if (((i * dump_width) + j) >= len) 68e1051a39Sopenharmony_ci break; 69e1051a39Sopenharmony_ci if (SPACE(buf, n, 1)) { 70e1051a39Sopenharmony_ci ch = *(s + i * dump_width + j) & 0xff; 71e1051a39Sopenharmony_ci#ifndef CHARSET_EBCDIC 72e1051a39Sopenharmony_ci buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.'; 73e1051a39Sopenharmony_ci#else 74e1051a39Sopenharmony_ci buf[n++] = ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) 75e1051a39Sopenharmony_ci ? os_toebcdic[ch] 76e1051a39Sopenharmony_ci : '.'; 77e1051a39Sopenharmony_ci#endif 78e1051a39Sopenharmony_ci buf[n] = '\0'; 79e1051a39Sopenharmony_ci } 80e1051a39Sopenharmony_ci } 81e1051a39Sopenharmony_ci if (SPACE(buf, n, 1)) { 82e1051a39Sopenharmony_ci buf[n++] = '\n'; 83e1051a39Sopenharmony_ci buf[n] = '\0'; 84e1051a39Sopenharmony_ci } 85e1051a39Sopenharmony_ci /* 86e1051a39Sopenharmony_ci * if this is the last call then update the ddt_dump thing so that we 87e1051a39Sopenharmony_ci * will move the selection point in the debug window 88e1051a39Sopenharmony_ci */ 89e1051a39Sopenharmony_ci res = cb((void *)buf, n, u); 90e1051a39Sopenharmony_ci if (res < 0) 91e1051a39Sopenharmony_ci return res; 92e1051a39Sopenharmony_ci ret += res; 93e1051a39Sopenharmony_ci } 94e1051a39Sopenharmony_ci return ret; 95e1051a39Sopenharmony_ci} 96e1051a39Sopenharmony_ci 97e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_STDIO 98e1051a39Sopenharmony_cistatic int write_fp(const void *data, size_t len, void *fp) 99e1051a39Sopenharmony_ci{ 100e1051a39Sopenharmony_ci return UP_fwrite(data, len, 1, fp); 101e1051a39Sopenharmony_ci} 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_ciint BIO_dump_fp(FILE *fp, const void *s, int len) 104e1051a39Sopenharmony_ci{ 105e1051a39Sopenharmony_ci return BIO_dump_cb(write_fp, fp, s, len); 106e1051a39Sopenharmony_ci} 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ciint BIO_dump_indent_fp(FILE *fp, const void *s, int len, int indent) 109e1051a39Sopenharmony_ci{ 110e1051a39Sopenharmony_ci return BIO_dump_indent_cb(write_fp, fp, s, len, indent); 111e1051a39Sopenharmony_ci} 112e1051a39Sopenharmony_ci#endif 113e1051a39Sopenharmony_ci 114e1051a39Sopenharmony_cistatic int write_bio(const void *data, size_t len, void *bp) 115e1051a39Sopenharmony_ci{ 116e1051a39Sopenharmony_ci return BIO_write((BIO *)bp, (const char *)data, len); 117e1051a39Sopenharmony_ci} 118e1051a39Sopenharmony_ci 119e1051a39Sopenharmony_ciint BIO_dump(BIO *bp, const void *s, int len) 120e1051a39Sopenharmony_ci{ 121e1051a39Sopenharmony_ci return BIO_dump_cb(write_bio, bp, s, len); 122e1051a39Sopenharmony_ci} 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ciint BIO_dump_indent(BIO *bp, const void *s, int len, int indent) 125e1051a39Sopenharmony_ci{ 126e1051a39Sopenharmony_ci return BIO_dump_indent_cb(write_bio, bp, s, len, indent); 127e1051a39Sopenharmony_ci} 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ciint BIO_hex_string(BIO *out, int indent, int width, const void *data, 130e1051a39Sopenharmony_ci int datalen) 131e1051a39Sopenharmony_ci{ 132e1051a39Sopenharmony_ci const unsigned char *d = data; 133e1051a39Sopenharmony_ci int i, j = 0; 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ci if (datalen < 1) 136e1051a39Sopenharmony_ci return 1; 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci for (i = 0; i < datalen - 1; i++) { 139e1051a39Sopenharmony_ci if (i && !j) 140e1051a39Sopenharmony_ci BIO_printf(out, "%*s", indent, ""); 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci BIO_printf(out, "%02X:", d[i]); 143e1051a39Sopenharmony_ci 144e1051a39Sopenharmony_ci j = (j + 1) % width; 145e1051a39Sopenharmony_ci if (!j) 146e1051a39Sopenharmony_ci BIO_printf(out, "\n"); 147e1051a39Sopenharmony_ci } 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci if (i && !j) 150e1051a39Sopenharmony_ci BIO_printf(out, "%*s", indent, ""); 151e1051a39Sopenharmony_ci BIO_printf(out, "%02X", d[datalen - 1]); 152e1051a39Sopenharmony_ci return 1; 153e1051a39Sopenharmony_ci} 154