aboutsummaryrefslogtreecommitdiff
path: root/openssl-1.1.0h/crypto/bio/b_dump.c
blob: 424195e16b3834f1f0a536fd0a3834f2d26ad88c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * Stolen from tjh's ssl/ssl_trc.c stuff.
 */

#include <stdio.h>
#include "bio_lcl.h"

#define DUMP_WIDTH      16
#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4))

int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
                void *u, const char *s, int len)
{
    return BIO_dump_indent_cb(cb, u, s, len, 0);
}

int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
                       void *u, const char *s, int len, int indent)
{
    int ret = 0;
    char buf[288 + 1], tmp[20], str[128 + 1];
    int i, j, rows;
    unsigned char ch;
    int dump_width;

    if (indent < 0)
        indent = 0;
    if (indent) {
        if (indent > 128)
            indent = 128;
        memset(str, ' ', indent);
    }
    str[indent] = '\0';

    dump_width = DUMP_WIDTH_LESS_INDENT(indent);
    rows = (len / dump_width);
    if ((rows * dump_width) < len)
        rows++;
    for (i = 0; i < rows; i++) {
        OPENSSL_strlcpy(buf, str, sizeof(buf));
        BIO_snprintf(tmp, sizeof(tmp), "%04x - ", i * dump_width);
        OPENSSL_strlcat(buf, tmp, sizeof(buf));
        for (j = 0; j < dump_width; j++) {
            if (((i * dump_width) + j) >= len) {
                OPENSSL_strlcat(buf, "   ", sizeof(buf));
            } else {
                ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
                BIO_snprintf(tmp, sizeof(tmp), "%02x%c", ch,
                             j == 7 ? '-' : ' ');
                OPENSSL_strlcat(buf, tmp, sizeof(buf));
            }
        }
        OPENSSL_strlcat(buf, "  ", sizeof(buf));
        for (j = 0; j < dump_width; j++) {
            if (((i * dump_width) + j) >= len)
                break;
            ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
#ifndef CHARSET_EBCDIC
            BIO_snprintf(tmp, sizeof(tmp), "%c",
                         ((ch >= ' ') && (ch <= '~')) ? ch : '.');
#else
            BIO_snprintf(tmp, sizeof(tmp), "%c",
                         ((ch >= os_toascii[' ']) && (ch <= os_toascii['~']))
                         ? os_toebcdic[ch]
                         : '.');
#endif
            OPENSSL_strlcat(buf, tmp, sizeof(buf));
        }
        OPENSSL_strlcat(buf, "\n", sizeof(buf));
        /*
         * if this is the last call then update the ddt_dump thing so that we
         * will move the selection point in the debug window
         */
        ret += cb((void *)buf, strlen(buf), u);
    }
    return ret;
}

#ifndef OPENSSL_NO_STDIO
static int write_fp(const void *data, size_t len, void *fp)
{
    return UP_fwrite(data, len, 1, fp);
}

int BIO_dump_fp(FILE *fp, const char *s, int len)
{
    return BIO_dump_cb(write_fp, fp, s, len);
}

int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
{
    return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
}
#endif

static int write_bio(const void *data, size_t len, void *bp)
{
    return BIO_write((BIO *)bp, (const char *)data, len);
}

int BIO_dump(BIO *bp, const char *s, int len)
{
    return BIO_dump_cb(write_bio, bp, s, len);
}

int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
{
    return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
}

int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
                   int datalen)
{
    int i, j = 0;

    if (datalen < 1)
        return 1;

    for (i = 0; i < datalen - 1; i++) {
        if (i && !j)
            BIO_printf(out, "%*s", indent, "");

        BIO_printf(out, "%02X:", data[i]);

        j = (j + 1) % width;
        if (!j)
            BIO_printf(out, "\n");
    }

    if (i && !j)
        BIO_printf(out, "%*s", indent, "");
    BIO_printf(out, "%02X", data[datalen - 1]);
    return 1;
}