/src/openssl31/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 | 26.2k | #define DUMP_WIDTH 16 |
18 | 26.2k | #define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH - ((i - (i > 6 ? 6 : i) + 3) / 4)) |
19 | | |
20 | 36.6M | #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 | 5.05k | { |
25 | 5.05k | return BIO_dump_indent_cb(cb, u, s, len, 0); |
26 | 5.05k | } |
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 | 26.2k | { |
31 | 26.2k | const unsigned char *s = v; |
32 | 26.2k | int res, ret = 0; |
33 | 26.2k | char buf[288 + 1]; |
34 | 26.2k | int i, j, rows, n; |
35 | 26.2k | unsigned char ch; |
36 | 26.2k | int dump_width; |
37 | | |
38 | 26.2k | if (indent < 0) |
39 | 0 | indent = 0; |
40 | 26.2k | else if (indent > 64) |
41 | 11 | indent = 64; |
42 | | |
43 | 26.2k | dump_width = DUMP_WIDTH_LESS_INDENT(indent); |
44 | 26.2k | rows = len / dump_width; |
45 | 26.2k | if ((rows * dump_width) < len) |
46 | 23.3k | rows++; |
47 | 1.13M | for (i = 0; i < rows; i++) { |
48 | 1.11M | n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "", |
49 | 1.11M | i * dump_width); |
50 | 18.4M | for (j = 0; j < dump_width; j++) { |
51 | 17.3M | if (SPACE(buf, n, 3)) { |
52 | 17.3M | if (((i * dump_width) + j) >= len) { |
53 | 204k | strcpy(buf + n, " "); |
54 | 17.1M | } else { |
55 | 17.1M | ch = *(s + i * dump_width + j) & 0xff; |
56 | 17.1M | BIO_snprintf(buf + n, 4, "%02x%c", ch, |
57 | 17.1M | j == 7 ? '-' : ' '); |
58 | 17.1M | } |
59 | 17.3M | n += 3; |
60 | 17.3M | } |
61 | 17.3M | } |
62 | 1.11M | if (SPACE(buf, n, 2)) { |
63 | 1.11M | strcpy(buf + n, " "); |
64 | 1.11M | n += 2; |
65 | 1.11M | } |
66 | 18.2M | for (j = 0; j < dump_width; j++) { |
67 | 17.1M | if (((i * dump_width) + j) >= len) |
68 | 23.3k | break; |
69 | 17.1M | if (SPACE(buf, n, 1)) { |
70 | 17.1M | ch = *(s + i * dump_width + j) & 0xff; |
71 | 17.1M | #ifndef CHARSET_EBCDIC |
72 | 17.1M | buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.'; |
73 | | #else |
74 | | buf[n++] = ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) |
75 | | ? os_toebcdic[ch] |
76 | | : '.'; |
77 | | #endif |
78 | 17.1M | buf[n] = '\0'; |
79 | 17.1M | } |
80 | 17.1M | } |
81 | 1.11M | if (SPACE(buf, n, 1)) { |
82 | 1.11M | buf[n++] = '\n'; |
83 | 1.11M | buf[n] = '\0'; |
84 | 1.11M | } |
85 | | /* |
86 | | * if this is the last call then update the ddt_dump thing so that we |
87 | | * will move the selection point in the debug window |
88 | | */ |
89 | 1.11M | res = cb((void *)buf, n, u); |
90 | 1.11M | if (res < 0) |
91 | 0 | return res; |
92 | 1.11M | ret += res; |
93 | 1.11M | } |
94 | 26.2k | return ret; |
95 | 26.2k | } |
96 | | |
97 | | #ifndef OPENSSL_NO_STDIO |
98 | | static int write_fp(const void *data, size_t len, void *fp) |
99 | 0 | { |
100 | 0 | return UP_fwrite(data, len, 1, fp); |
101 | 0 | } |
102 | | |
103 | | int BIO_dump_fp(FILE *fp, const void *s, int len) |
104 | 0 | { |
105 | 0 | return BIO_dump_cb(write_fp, fp, s, len); |
106 | 0 | } |
107 | | |
108 | | int BIO_dump_indent_fp(FILE *fp, const void *s, int len, int indent) |
109 | 0 | { |
110 | 0 | return BIO_dump_indent_cb(write_fp, fp, s, len, indent); |
111 | 0 | } |
112 | | #endif |
113 | | |
114 | | static int write_bio(const void *data, size_t len, void *bp) |
115 | 7.30M | { |
116 | 7.30M | return BIO_write((BIO *)bp, (const char *)data, len); |
117 | 7.30M | } |
118 | | |
119 | | int BIO_dump(BIO *bp, const void *s, int len) |
120 | 5.05k | { |
121 | 5.05k | return BIO_dump_cb(write_bio, bp, s, len); |
122 | 5.05k | } |
123 | | |
124 | | int BIO_dump_indent(BIO *bp, const void *s, int len, int indent) |
125 | 127k | { |
126 | 127k | return BIO_dump_indent_cb(write_bio, bp, s, len, indent); |
127 | 127k | } |
128 | | |
129 | | int BIO_hex_string(BIO *out, int indent, int width, const void *data, |
130 | | int datalen) |
131 | 482k | { |
132 | 482k | const unsigned char *d = data; |
133 | 482k | int i, j = 0; |
134 | | |
135 | 482k | if (datalen < 1) |
136 | 17.8k | return 1; |
137 | | |
138 | 8.77M | for (i = 0; i < datalen - 1; i++) { |
139 | 8.30M | if (i && !j) |
140 | 464k | BIO_printf(out, "%*s", indent, ""); |
141 | | |
142 | 8.30M | BIO_printf(out, "%02X:", d[i]); |
143 | | |
144 | 8.30M | j = (j + 1) % width; |
145 | 8.30M | if (!j) |
146 | 469k | BIO_printf(out, "\n"); |
147 | 8.30M | } |
148 | | |
149 | 465k | if (i && !j) |
150 | 4.99k | BIO_printf(out, "%*s", indent, ""); |
151 | 465k | BIO_printf(out, "%02X", d[datalen - 1]); |
152 | 465k | return 1; |
153 | 482k | } |