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