/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 | for (j = 0; j < dump_width; j++) { |
51 | 0 | if (SPACE(buf, n, 3)) { |
52 | 0 | if (((i * dump_width) + j) >= len) { |
53 | 0 | strcpy(buf + n, " "); |
54 | 0 | } else { |
55 | 0 | ch = *(s + i * dump_width + j) & 0xff; |
56 | 0 | BIO_snprintf(buf + n, 4, "%02x%c", ch, |
57 | 0 | j == 7 ? '-' : ' '); |
58 | 0 | } |
59 | 0 | n += 3; |
60 | 0 | } |
61 | 0 | } |
62 | 0 | if (SPACE(buf, n, 2)) { |
63 | 0 | strcpy(buf + n, " "); |
64 | 0 | n += 2; |
65 | 0 | } |
66 | 0 | for (j = 0; j < dump_width; j++) { |
67 | 0 | if (((i * dump_width) + j) >= len) |
68 | 0 | break; |
69 | 0 | if (SPACE(buf, n, 1)) { |
70 | 0 | ch = *(s + i * dump_width + j) & 0xff; |
71 | 0 | #ifndef CHARSET_EBCDIC |
72 | 0 | buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.'; |
73 | | #else |
74 | | buf[n++] = ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) |
75 | | ? os_toebcdic[ch] |
76 | | : '.'; |
77 | | #endif |
78 | 0 | buf[n] = '\0'; |
79 | 0 | } |
80 | 0 | } |
81 | 0 | if (SPACE(buf, n, 1)) { |
82 | 0 | buf[n++] = '\n'; |
83 | 0 | buf[n] = '\0'; |
84 | 0 | } |
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 | 0 | res = cb((void *)buf, n, u); |
90 | 0 | if (res < 0) |
91 | 0 | return res; |
92 | 0 | ret += res; |
93 | 0 | } |
94 | 0 | return ret; |
95 | 0 | } |
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 | 0 | { |
116 | 0 | return BIO_write((BIO *)bp, (const char *)data, len); |
117 | 0 | } |
118 | | |
119 | | int BIO_dump(BIO *bp, const void *s, int len) |
120 | 0 | { |
121 | 0 | return BIO_dump_cb(write_bio, bp, s, len); |
122 | 0 | } |
123 | | |
124 | | int BIO_dump_indent(BIO *bp, const void *s, int len, int indent) |
125 | 0 | { |
126 | 0 | return BIO_dump_indent_cb(write_bio, bp, s, len, indent); |
127 | 0 | } |
128 | | |
129 | | int BIO_hex_string(BIO *out, int indent, int width, const void *data, |
130 | | int datalen) |
131 | 0 | { |
132 | 0 | const unsigned char *d = data; |
133 | 0 | int i, j = 0; |
134 | |
|
135 | 0 | if (datalen < 1) |
136 | 0 | return 1; |
137 | | |
138 | 0 | for (i = 0; i < datalen - 1; i++) { |
139 | 0 | if (i && !j) |
140 | 0 | BIO_printf(out, "%*s", indent, ""); |
141 | |
|
142 | 0 | BIO_printf(out, "%02X:", d[i]); |
143 | |
|
144 | 0 | if (++j >= width) { |
145 | 0 | j = 0; |
146 | 0 | BIO_printf(out, "\n"); |
147 | 0 | } |
148 | 0 | } |
149 | |
|
150 | 0 | if (i && !j) |
151 | 0 | BIO_printf(out, "%*s", indent, ""); |
152 | 0 | BIO_printf(out, "%02X", d[datalen - 1]); |
153 | 0 | return 1; |
154 | 0 | } |