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