1 /*
2 * Copyright 2022-2023 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 #include <openssl/trace.h>
11
12 #include "testutil.h"
13
test_trace_categories(void)14 static int test_trace_categories(void)
15 {
16 int cat_num;
17
18 for (cat_num = -1; cat_num <= OSSL_TRACE_CATEGORY_NUM + 1; ++cat_num) {
19 const char *cat_name = OSSL_trace_get_category_name(cat_num);
20 const char *expected_cat_name = NULL;
21 int ret_cat_num;
22
23 #define SET_EXPECTED_CAT_NAME(name) \
24 expected_cat_name = #name; \
25 break
26 switch (cat_num) {
27 case OSSL_TRACE_CATEGORY_ALL:
28 SET_EXPECTED_CAT_NAME(ALL);
29 case OSSL_TRACE_CATEGORY_TRACE:
30 SET_EXPECTED_CAT_NAME(TRACE);
31 case OSSL_TRACE_CATEGORY_INIT:
32 SET_EXPECTED_CAT_NAME(INIT);
33 case OSSL_TRACE_CATEGORY_TLS:
34 SET_EXPECTED_CAT_NAME(TLS);
35 case OSSL_TRACE_CATEGORY_TLS_CIPHER:
36 SET_EXPECTED_CAT_NAME(TLS_CIPHER);
37 case OSSL_TRACE_CATEGORY_CONF:
38 SET_EXPECTED_CAT_NAME(CONF);
39 case OSSL_TRACE_CATEGORY_ENGINE_TABLE:
40 SET_EXPECTED_CAT_NAME(ENGINE_TABLE);
41 case OSSL_TRACE_CATEGORY_ENGINE_REF_COUNT:
42 SET_EXPECTED_CAT_NAME(ENGINE_REF_COUNT);
43 case OSSL_TRACE_CATEGORY_PKCS5V2:
44 SET_EXPECTED_CAT_NAME(PKCS5V2);
45 case OSSL_TRACE_CATEGORY_PKCS12_KEYGEN:
46 SET_EXPECTED_CAT_NAME(PKCS12_KEYGEN);
47 case OSSL_TRACE_CATEGORY_PKCS12_DECRYPT:
48 SET_EXPECTED_CAT_NAME(PKCS12_DECRYPT);
49 case OSSL_TRACE_CATEGORY_X509V3_POLICY:
50 SET_EXPECTED_CAT_NAME(X509V3_POLICY);
51 case OSSL_TRACE_CATEGORY_BN_CTX:
52 SET_EXPECTED_CAT_NAME(BN_CTX);
53 case OSSL_TRACE_CATEGORY_CMP:
54 SET_EXPECTED_CAT_NAME(CMP);
55 case OSSL_TRACE_CATEGORY_STORE:
56 SET_EXPECTED_CAT_NAME(STORE);
57 case OSSL_TRACE_CATEGORY_DECODER:
58 SET_EXPECTED_CAT_NAME(DECODER);
59 case OSSL_TRACE_CATEGORY_ENCODER:
60 SET_EXPECTED_CAT_NAME(ENCODER);
61 case OSSL_TRACE_CATEGORY_REF_COUNT:
62 SET_EXPECTED_CAT_NAME(REF_COUNT);
63 case OSSL_TRACE_CATEGORY_HTTP:
64 SET_EXPECTED_CAT_NAME(HTTP);
65 case OSSL_TRACE_CATEGORY_PROVIDER:
66 SET_EXPECTED_CAT_NAME(PROVIDER);
67 case OSSL_TRACE_CATEGORY_QUERY:
68 SET_EXPECTED_CAT_NAME(QUERY);
69 default:
70 if (cat_num == -1 || cat_num >= OSSL_TRACE_CATEGORY_NUM)
71 expected_cat_name = NULL;
72 break;
73 }
74 #undef SET_EXPECTED_CAT_NAME
75
76 if (!TEST_str_eq(cat_name, expected_cat_name))
77 return 0;
78 ret_cat_num = OSSL_trace_get_category_num(cat_name);
79 if (cat_num < OSSL_TRACE_CATEGORY_NUM)
80 if (!TEST_int_eq(cat_num, ret_cat_num))
81 return 0;
82 }
83
84 return 1;
85 }
86
87 #ifndef OPENSSL_NO_TRACE
88
89 #define OSSL_START "xyz-"
90 #define OSSL_HELLO "Hello World\n"
91 /* OSSL_STR80 must have length OSSL_TRACE_STRING_MAX */
92 #define OSSL_STR80 "1234567890123456789012345678901234567890123456789012345678901234567890123456789\n"
93 #define OSSL_STR81 (OSSL_STR80 "x")
94 #define OSSL_CTRL "A\xfe\nB"
95 #define OSSL_MASKED "A \nB"
96 #define OSSL_BYE "Good Bye Universe\n"
97 #define OSSL_END "-abc"
98
99 #define trace_string(text, full, str) \
100 OSSL_trace_string(trc_out, text, full, (unsigned char *)(str), strlen(str))
101
put_trace_output(void)102 static int put_trace_output(void)
103 {
104 int res = 1;
105
106 OSSL_TRACE_BEGIN(HTTP)
107 {
108 res = TEST_int_eq(BIO_printf(trc_out, OSSL_HELLO), strlen(OSSL_HELLO));
109 res += TEST_int_eq(trace_string(0, 0, OSSL_STR80), strlen(OSSL_STR80));
110 res += TEST_int_eq(trace_string(0, 0, OSSL_STR81), strlen(OSSL_STR80));
111 res += TEST_int_eq(trace_string(1, 1, OSSL_CTRL), strlen(OSSL_CTRL));
112 res += TEST_int_eq(trace_string(0, 1, OSSL_MASKED), strlen(OSSL_MASKED) + 1); /* newline added */
113 res += TEST_int_eq(BIO_printf(trc_out, OSSL_BYE), strlen(OSSL_BYE));
114 res = res == 6;
115 /* not using '&&' but '+' to catch potentially multiple test failures */
116 }
117 OSSL_TRACE_END(HTTP);
118 return res;
119 }
120
test_trace_channel(void)121 static int test_trace_channel(void)
122 {
123 static const char expected[] = OSSL_START "\n" OSSL_HELLO OSSL_STR80 "[len 81 limited to 80]: " OSSL_STR80
124 OSSL_CTRL OSSL_MASKED "\n" OSSL_BYE OSSL_END "\n";
125 static const size_t expected_len = sizeof(expected) - 1;
126 BIO *bio = NULL;
127 char *p_buf = NULL;
128 long len = 0;
129 int ret = 0;
130
131 bio = BIO_new(BIO_s_mem());
132 if (!TEST_ptr(bio))
133 goto end;
134
135 if (!TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_HTTP, bio), 1)) {
136 BIO_free(bio);
137 goto end;
138 }
139
140 if (!TEST_true(OSSL_trace_enabled(OSSL_TRACE_CATEGORY_HTTP)))
141 goto end;
142
143 if (!TEST_int_eq(OSSL_trace_set_prefix(OSSL_TRACE_CATEGORY_HTTP,
144 OSSL_START),
145 1))
146 goto end;
147 if (!TEST_int_eq(OSSL_trace_set_suffix(OSSL_TRACE_CATEGORY_HTTP,
148 OSSL_END),
149 1))
150 goto end;
151
152 ret = put_trace_output();
153 len = BIO_get_mem_data(bio, &p_buf);
154 if (!TEST_strn2_eq(p_buf, len, expected, expected_len))
155 ret = 0;
156 ret = TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_HTTP, NULL), 1)
157 && ret;
158
159 end:
160 return ret;
161 }
162
163 static int trace_cb_failure;
164 static int trace_cb_called;
165
trace_cb(const char * buffer,size_t count,int category,int cmd,void * data)166 static size_t trace_cb(const char *buffer, size_t count,
167 int category, int cmd, void *data)
168 {
169 trace_cb_called = 1;
170 if (!TEST_true(category == OSSL_TRACE_CATEGORY_TRACE))
171 trace_cb_failure = 1;
172 return count;
173 }
174
test_trace_callback(void)175 static int test_trace_callback(void)
176 {
177 int ret = 0;
178
179 if (!TEST_true(OSSL_trace_set_callback(OSSL_TRACE_CATEGORY_TRACE, trace_cb,
180 NULL)))
181 goto end;
182
183 put_trace_output();
184
185 if (!TEST_false(trace_cb_failure) || !TEST_true(trace_cb_called))
186 goto end;
187
188 ret = 1;
189 end:
190 return ret;
191 }
192 #endif
193
194 OPT_TEST_DECLARE_USAGE("\n")
195
setup_tests(void)196 int setup_tests(void)
197 {
198 if (!test_skip_common_options()) {
199 TEST_error("Error parsing test options\n");
200 return 0;
201 }
202
203 ADD_TEST(test_trace_categories);
204 #ifndef OPENSSL_NO_TRACE
205 ADD_TEST(test_trace_channel);
206 ADD_TEST(test_trace_callback);
207 #endif
208 return 1;
209 }
210
cleanup_tests(void)211 void cleanup_tests(void)
212 {
213 }
214