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 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 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 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 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 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 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 211 void cleanup_tests(void) 212 { 213 } 214