]>
Commit | Line | Data |
---|---|---|
b1322259 | 1 | /* |
59e539e6 | 2 | * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. |
0f113f3e | 3 | * |
b1322259 RS |
4 | * Licensed under the OpenSSL license (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 | |
d02b48c6 RE |
8 | */ |
9 | ||
0f113f3e | 10 | /* |
d02b48c6 RE |
11 | * Stolen from tjh's ssl/ssl_trc.c stuff. |
12 | */ | |
13 | ||
14 | #include <stdio.h> | |
ea1b02db | 15 | #include "bio_lcl.h" |
d02b48c6 RE |
16 | |
17 | #define TRUNCATE | |
0f113f3e | 18 | #define DUMP_WIDTH 16 |
59e539e6 P |
19 | #define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH - ((i - (i > 6 ? 6 : i) + 3) / 4)) |
20 | ||
21 | #define SPACE(buf, pos, n) (sizeof(buf) - (pos) > (n)) | |
d02b48c6 | 22 | |
0f113f3e MC |
23 | int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), |
24 | void *u, const char *s, int len) | |
25 | { | |
26 | return BIO_dump_indent_cb(cb, u, s, len, 0); | |
27 | } | |
ca1e465f | 28 | |
0f113f3e MC |
29 | int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), |
30 | void *u, const char *s, int len, int indent) | |
31 | { | |
32 | int ret = 0; | |
59e539e6 P |
33 | char buf[288 + 1]; |
34 | int i, j, rows, trc, n; | |
0f113f3e MC |
35 | unsigned char ch; |
36 | int dump_width; | |
bb1a915c | 37 | |
0f113f3e | 38 | trc = 0; |
bb1a915c | 39 | |
d02b48c6 | 40 | #ifdef TRUNCATE |
0f113f3e MC |
41 | for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--) |
42 | trc++; | |
d02b48c6 RE |
43 | #endif |
44 | ||
0f113f3e MC |
45 | if (indent < 0) |
46 | indent = 0; | |
59e539e6 P |
47 | else if (indent > 128) |
48 | indent = 128; | |
0f113f3e MC |
49 | |
50 | dump_width = DUMP_WIDTH_LESS_INDENT(indent); | |
59e539e6 | 51 | rows = len / dump_width; |
0f113f3e MC |
52 | if ((rows * dump_width) < len) |
53 | rows++; | |
54 | for (i = 0; i < rows; i++) { | |
59e539e6 P |
55 | n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "", |
56 | i * dump_width); | |
0f113f3e | 57 | for (j = 0; j < dump_width; j++) { |
59e539e6 P |
58 | if (SPACE(buf, n, 3)) { |
59 | if (((i * dump_width) + j) >= len) { | |
60 | strcpy(buf + n, " "); | |
61 | } else { | |
62 | ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; | |
63 | BIO_snprintf(buf + n, 4, "%02x%c", ch, | |
64 | j == 7 ? '-' : ' '); | |
65 | } | |
66 | n += 3; | |
0f113f3e MC |
67 | } |
68 | } | |
59e539e6 P |
69 | if (SPACE(buf, n, 2)) { |
70 | strcpy(buf + n, " "); | |
71 | n += 2; | |
72 | } | |
0f113f3e MC |
73 | for (j = 0; j < dump_width; j++) { |
74 | if (((i * dump_width) + j) >= len) | |
75 | break; | |
59e539e6 P |
76 | if (SPACE(buf, n, 1)) { |
77 | ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; | |
a53955d8 | 78 | #ifndef CHARSET_EBCDIC |
59e539e6 | 79 | buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.'; |
a53955d8 | 80 | #else |
59e539e6 P |
81 | buf[n++] = ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) |
82 | ? os_toebcdic[ch] | |
83 | : '.'; | |
a53955d8 | 84 | #endif |
59e539e6 P |
85 | buf[n] = '\0'; |
86 | } | |
87 | } | |
88 | if (SPACE(buf, n, 1)) { | |
89 | buf[n++] = '\n'; | |
90 | buf[n] = '\0'; | |
0f113f3e | 91 | } |
0f113f3e MC |
92 | /* |
93 | * if this is the last call then update the ddt_dump thing so that we | |
94 | * will move the selection point in the debug window | |
95 | */ | |
59e539e6 | 96 | ret += cb((void *)buf, n, u); |
0f113f3e | 97 | } |
d02b48c6 | 98 | #ifdef TRUNCATE |
0f113f3e | 99 | if (trc > 0) { |
59e539e6 P |
100 | n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - <SPACES/NULS>\n", |
101 | indent, "", len + trc); | |
102 | ret += cb((void *)buf, n, u); | |
0f113f3e | 103 | } |
d02b48c6 | 104 | #endif |
59e539e6 | 105 | return ret; |
0f113f3e | 106 | } |
bb1a915c | 107 | |
4b618848 | 108 | #ifndef OPENSSL_NO_STDIO |
bb1a915c | 109 | static int write_fp(const void *data, size_t len, void *fp) |
0f113f3e MC |
110 | { |
111 | return UP_fwrite(data, len, 1, fp); | |
112 | } | |
113 | ||
bb1a915c | 114 | int BIO_dump_fp(FILE *fp, const char *s, int len) |
0f113f3e MC |
115 | { |
116 | return BIO_dump_cb(write_fp, fp, s, len); | |
117 | } | |
118 | ||
bb1a915c | 119 | int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent) |
0f113f3e MC |
120 | { |
121 | return BIO_dump_indent_cb(write_fp, fp, s, len, indent); | |
122 | } | |
bb1a915c RL |
123 | #endif |
124 | ||
125 | static int write_bio(const void *data, size_t len, void *bp) | |
0f113f3e MC |
126 | { |
127 | return BIO_write((BIO *)bp, (const char *)data, len); | |
128 | } | |
129 | ||
bb1a915c | 130 | int BIO_dump(BIO *bp, const char *s, int len) |
0f113f3e MC |
131 | { |
132 | return BIO_dump_cb(write_bio, bp, s, len); | |
133 | } | |
134 | ||
bb1a915c | 135 | int BIO_dump_indent(BIO *bp, const char *s, int len, int indent) |
0f113f3e MC |
136 | { |
137 | return BIO_dump_indent_cb(write_bio, bp, s, len, indent); | |
138 | } | |
bb1a915c | 139 | |
b263f212 | 140 | int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, |
0f113f3e MC |
141 | int datalen) |
142 | { | |
143 | int i, j = 0; | |
b263f212 | 144 | |
0f113f3e MC |
145 | if (datalen < 1) |
146 | return 1; | |
b263f212 | 147 | |
0f113f3e MC |
148 | for (i = 0; i < datalen - 1; i++) { |
149 | if (i && !j) | |
150 | BIO_printf(out, "%*s", indent, ""); | |
b263f212 | 151 | |
0f113f3e | 152 | BIO_printf(out, "%02X:", data[i]); |
b263f212 | 153 | |
0f113f3e MC |
154 | j = (j + 1) % width; |
155 | if (!j) | |
156 | BIO_printf(out, "\n"); | |
157 | } | |
b263f212 | 158 | |
0f113f3e MC |
159 | if (i && !j) |
160 | BIO_printf(out, "%*s", indent, ""); | |
161 | BIO_printf(out, "%02X", data[datalen - 1]); | |
162 | return 1; | |
163 | } |