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 
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 #undef CASE
49         default:
50             is_cat_name_eq = TEST_ptr_null(cat_name);
51             break;
52         }
53 
54         if (!TEST_true(is_cat_name_eq))
55             return 0;
56         ret_cat_num =
57             OSSL_trace_get_category_num(cat_name);
58         expected_ret = cat_name != NULL ? cat_num : -1;
59         if (!TEST_int_eq(expected_ret, ret_cat_num))
60             return 0;
61     }
62 
63     return 1;
64 }
65 
66 #ifndef OPENSSL_NO_TRACE
67 static void put_trace_output(void)
68 {
69     OSSL_TRACE_BEGIN(REF_COUNT) {
70         BIO_printf(trc_out, "Hello World\n");
71         BIO_printf(trc_out, "Good Bye Universe\n");
72     } OSSL_TRACE_END(REF_COUNT);
73 }
74 
75 static int test_trace_channel(void)
76 {
77     static const char expected[] = "xyz-\nHello World\nGood Bye Universe\n-abc\n";
78     static const char expected_len = sizeof(expected) - 1;
79     BIO *bio = NULL;
80     char *p_buf = NULL;
81     long len = 0;
82     int ret = 0;
83 
84     bio = BIO_new(BIO_s_mem());
85     if (!TEST_ptr(bio))
86         goto end;
87 
88     if (!TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_REF_COUNT, bio), 1))
89         goto end;
90 
91     if (!TEST_true(OSSL_trace_enabled(OSSL_TRACE_CATEGORY_REF_COUNT)))
92         goto end;
93 
94     if (!TEST_int_eq(OSSL_trace_set_prefix(OSSL_TRACE_CATEGORY_REF_COUNT, "xyz-"), 1))
95         goto end;
96     if (!TEST_int_eq(OSSL_trace_set_suffix(OSSL_TRACE_CATEGORY_REF_COUNT, "-abc"), 1))
97         goto end;
98 
99     put_trace_output();
100     len = BIO_get_mem_data(bio, &p_buf);
101     if (!TEST_strn2_eq(p_buf, len, expected, expected_len))
102         goto end;
103     if (!TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_REF_COUNT, NULL), 1))
104         goto end;
105     bio = NULL;
106 
107     ret = 1;
108  end:
109     BIO_free(bio);
110     return ret;
111 }
112 
113 static int trace_cb_failure;
114 static int trace_cb_called;
115 
116 static size_t trace_cb(const char *buffer, size_t count,
117                        int category, int cmd, void *data)
118 {
119     trace_cb_called = 1;
120     if (!TEST_true(category == OSSL_TRACE_CATEGORY_TRACE))
121         trace_cb_failure = 1;
122     return count;
123 }
124 
125 static int test_trace_callback(void)
126 {
127     int ret = 0;
128 
129     if (!TEST_true(OSSL_trace_set_callback(OSSL_TRACE_CATEGORY_TRACE, trace_cb,
130                                            NULL)))
131         goto end;
132 
133     put_trace_output();
134 
135     if (!TEST_false(trace_cb_failure) || !TEST_true(trace_cb_called))
136         goto end;
137 
138     ret = 1;
139  end:
140     return ret;
141 }
142 #endif
143 
144 OPT_TEST_DECLARE_USAGE("\n")
145 
146 int setup_tests(void)
147 {
148     if (!test_skip_common_options()) {
149         TEST_error("Error parsing test options\n");
150         return 0;
151     }
152 
153     ADD_TEST(test_trace_categories);
154 #ifndef OPENSSL_NO_TRACE
155     ADD_TEST(test_trace_channel);
156     ADD_TEST(test_trace_callback);
157 #endif
158     return 1;
159 }
160 
161 void cleanup_tests(void)
162 {
163 }
164