/src/openssl32/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 | 106k | #define DUMP_WIDTH 16 |
18 | 106k | #define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH - ((i - (i > 6 ? 6 : i) + 3) / 4)) |
19 | | |
20 | 195M | #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 | 106k | { |
31 | 106k | const unsigned char *s = v; |
32 | 106k | int res, ret = 0; |
33 | 106k | char buf[288 + 1]; |
34 | 106k | int i, j, rows, n; |
35 | 106k | unsigned char ch; |
36 | 106k | int dump_width; |
37 | | |
38 | 106k | if (indent < 0) |
39 | 0 | indent = 0; |
40 | 106k | else if (indent > 64) |
41 | 49 | indent = 64; |
42 | | |
43 | 106k | dump_width = DUMP_WIDTH_LESS_INDENT(indent); |
44 | 106k | rows = len / dump_width; |
45 | 106k | if ((rows * dump_width) < len) |
46 | 96.7k | rows++; |
47 | 6.30M | for (i = 0; i < rows; i++) { |
48 | 6.19M | n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "", |
49 | 6.19M | i * dump_width); |
50 | 6.19M | if (n < 0) |
51 | 0 | return -1; |
52 | 98.1M | for (j = 0; j < dump_width; j++) { |
53 | 91.9M | if (SPACE(buf, n, 3)) { |
54 | 91.9M | if (((i * dump_width) + j) >= len) { |
55 | 1.08M | strcpy(buf + n, " "); |
56 | 90.8M | } else { |
57 | 90.8M | ch = *(s + i * dump_width + j) & 0xff; |
58 | 90.8M | BIO_snprintf(buf + n, 4, "%02x%c", ch, |
59 | 90.8M | j == 7 ? '-' : ' '); |
60 | 90.8M | } |
61 | 91.9M | n += 3; |
62 | 91.9M | } |
63 | 91.9M | } |
64 | 6.19M | if (SPACE(buf, n, 2)) { |
65 | 6.19M | strcpy(buf + n, " "); |
66 | 6.19M | n += 2; |
67 | 6.19M | } |
68 | 97.0M | for (j = 0; j < dump_width; j++) { |
69 | 90.9M | if (((i * dump_width) + j) >= len) |
70 | 96.7k | break; |
71 | 90.8M | if (SPACE(buf, n, 1)) { |
72 | 90.8M | ch = *(s + i * dump_width + j) & 0xff; |
73 | 90.8M | #ifndef CHARSET_EBCDIC |
74 | 90.8M | buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.'; |
75 | | #else |
76 | | buf[n++] = ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) |
77 | | ? os_toebcdic[ch] |
78 | | : '.'; |
79 | | #endif |
80 | 90.8M | buf[n] = '\0'; |
81 | 90.8M | } |
82 | 90.8M | } |
83 | 6.19M | if (SPACE(buf, n, 1)) { |
84 | 6.19M | buf[n++] = '\n'; |
85 | 6.19M | buf[n] = '\0'; |
86 | 6.19M | } |
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 | 6.19M | res = cb((void *)buf, n, u); |
92 | 6.19M | if (res < 0) |
93 | 0 | return res; |
94 | 6.19M | ret += res; |
95 | 6.19M | } |
96 | 106k | return ret; |
97 | 106k | } |
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 | 7.30M | { |
118 | 7.30M | return BIO_write((BIO *)bp, (const char *)data, len); |
119 | 7.30M | } |
120 | | |
121 | | int BIO_dump(BIO *bp, const void *s, int len) |
122 | 5.05k | { |
123 | 5.05k | return BIO_dump_cb(write_bio, bp, s, len); |
124 | 5.05k | } |
125 | | |
126 | | int BIO_dump_indent(BIO *bp, const void *s, int len, int indent) |
127 | 127k | { |
128 | 127k | return BIO_dump_indent_cb(write_bio, bp, s, len, indent); |
129 | 127k | } |
130 | | |
131 | | int BIO_hex_string(BIO *out, int indent, int width, const void *data, |
132 | | int datalen) |
133 | 482k | { |
134 | 482k | const unsigned char *d = data; |
135 | 482k | int i, j = 0; |
136 | | |
137 | 482k | if (datalen < 1) |
138 | 17.8k | return 1; |
139 | | |
140 | 8.77M | for (i = 0; i < datalen - 1; i++) { |
141 | 8.30M | if (i && !j) |
142 | 464k | BIO_printf(out, "%*s", indent, ""); |
143 | | |
144 | 8.30M | BIO_printf(out, "%02X:", d[i]); |
145 | | |
146 | 8.30M | j = (j + 1) % width; |
147 | 8.30M | if (!j) |
148 | 469k | BIO_printf(out, "\n"); |
149 | 8.30M | } |
150 | | |
151 | 465k | if (i && !j) |
152 | 4.99k | BIO_printf(out, "%*s", indent, ""); |
153 | 465k | BIO_printf(out, "%02X", d[datalen - 1]); |
154 | 465k | return 1; |
155 | 482k | } |