/src/openssl/crypto/bio/b_dump.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
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 |
8 | | */ |
9 | | |
10 | | /* |
11 | | * Stolen from tjh's ssl/ssl_trc.c stuff. |
12 | | */ |
13 | | |
14 | | #include <stdio.h> |
15 | | #include "bio_lcl.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 char *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 char *s, int len, int indent) |
30 | 0 | { |
31 | 0 | int ret = 0; |
32 | 0 | char buf[288 + 1]; |
33 | 0 | int i, j, rows, n; |
34 | 0 | unsigned char ch; |
35 | 0 | int dump_width; |
36 | 0 |
|
37 | 0 | if (indent < 0) |
38 | 0 | indent = 0; |
39 | 0 | else if (indent > 128) |
40 | 0 | indent = 128; |
41 | 0 |
|
42 | 0 | dump_width = DUMP_WIDTH_LESS_INDENT(indent); |
43 | 0 | rows = len / dump_width; |
44 | 0 | if ((rows * dump_width) < len) |
45 | 0 | rows++; |
46 | 0 | for (i = 0; i < rows; i++) { |
47 | 0 | n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "", |
48 | 0 | i * dump_width); |
49 | 0 | for (j = 0; j < dump_width; j++) { |
50 | 0 | if (SPACE(buf, n, 3)) { |
51 | 0 | if (((i * dump_width) + j) >= len) { |
52 | 0 | strcpy(buf + n, " "); |
53 | 0 | } else { |
54 | 0 | ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; |
55 | 0 | BIO_snprintf(buf + n, 4, "%02x%c", ch, |
56 | 0 | j == 7 ? '-' : ' '); |
57 | 0 | } |
58 | 0 | n += 3; |
59 | 0 | } |
60 | 0 | } |
61 | 0 | if (SPACE(buf, n, 2)) { |
62 | 0 | strcpy(buf + n, " "); |
63 | 0 | n += 2; |
64 | 0 | } |
65 | 0 | for (j = 0; j < dump_width; j++) { |
66 | 0 | if (((i * dump_width) + j) >= len) |
67 | 0 | break; |
68 | 0 | if (SPACE(buf, n, 1)) { |
69 | 0 | ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; |
70 | 0 | #ifndef CHARSET_EBCDIC |
71 | 0 | buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.'; |
72 | | #else |
73 | | buf[n++] = ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) |
74 | | ? os_toebcdic[ch] |
75 | | : '.'; |
76 | | #endif |
77 | | buf[n] = '\0'; |
78 | 0 | } |
79 | 0 | } |
80 | 0 | if (SPACE(buf, n, 1)) { |
81 | 0 | buf[n++] = '\n'; |
82 | 0 | buf[n] = '\0'; |
83 | 0 | } |
84 | 0 | /* |
85 | 0 | * if this is the last call then update the ddt_dump thing so that we |
86 | 0 | * will move the selection point in the debug window |
87 | 0 | */ |
88 | 0 | ret += cb((void *)buf, n, u); |
89 | 0 | } |
90 | 0 | return ret; |
91 | 0 | } |
92 | | |
93 | | #ifndef OPENSSL_NO_STDIO |
94 | | static int write_fp(const void *data, size_t len, void *fp) |
95 | 0 | { |
96 | 0 | return UP_fwrite(data, len, 1, fp); |
97 | 0 | } |
98 | | |
99 | | int BIO_dump_fp(FILE *fp, const char *s, int len) |
100 | 0 | { |
101 | 0 | return BIO_dump_cb(write_fp, fp, s, len); |
102 | 0 | } |
103 | | |
104 | | int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent) |
105 | 0 | { |
106 | 0 | return BIO_dump_indent_cb(write_fp, fp, s, len, indent); |
107 | 0 | } |
108 | | #endif |
109 | | |
110 | | static int write_bio(const void *data, size_t len, void *bp) |
111 | 0 | { |
112 | 0 | return BIO_write((BIO *)bp, (const char *)data, len); |
113 | 0 | } |
114 | | |
115 | | int BIO_dump(BIO *bp, const char *s, int len) |
116 | 0 | { |
117 | 0 | return BIO_dump_cb(write_bio, bp, s, len); |
118 | 0 | } |
119 | | |
120 | | int BIO_dump_indent(BIO *bp, const char *s, int len, int indent) |
121 | 0 | { |
122 | 0 | return BIO_dump_indent_cb(write_bio, bp, s, len, indent); |
123 | 0 | } |
124 | | |
125 | | int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, |
126 | | int datalen) |
127 | 0 | { |
128 | 0 | int i, j = 0; |
129 | 0 |
|
130 | 0 | if (datalen < 1) |
131 | 0 | return 1; |
132 | 0 | |
133 | 0 | for (i = 0; i < datalen - 1; i++) { |
134 | 0 | if (i && !j) |
135 | 0 | BIO_printf(out, "%*s", indent, ""); |
136 | 0 |
|
137 | 0 | BIO_printf(out, "%02X:", data[i]); |
138 | 0 |
|
139 | 0 | j = (j + 1) % width; |
140 | 0 | if (!j) |
141 | 0 | BIO_printf(out, "\n"); |
142 | 0 | } |
143 | 0 |
|
144 | 0 | if (i && !j) |
145 | 0 | BIO_printf(out, "%*s", indent, ""); |
146 | 0 | BIO_printf(out, "%02X", data[datalen - 1]); |
147 | 0 | return 1; |
148 | 0 | } |