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