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