diff options
-rw-r--r-- | crypto/trace.c | 25 | ||||
-rw-r--r-- | doc/man3/OSSL_trace_enabled.pod | 28 | ||||
-rw-r--r-- | include/openssl/trace.h | 8 | ||||
-rw-r--r-- | test/trace_api_test.c | 58 | ||||
-rw-r--r-- | util/libcrypto.num | 1 |
5 files changed, 104 insertions, 16 deletions
diff --git a/crypto/trace.c b/crypto/trace.c index 3bf9ff62f7..8e5836de32 100644 --- a/crypto/trace.c +++ b/crypto/trace.c @@ -18,6 +18,7 @@ #include "internal/nelem.h" #include "internal/refcount.h" #include "crypto/cryptlib.h" +#include "crypto/ctype.h" #ifndef OPENSSL_NO_TRACE @@ -530,3 +531,27 @@ void OSSL_trace_end(int category, BIO * channel) } #endif } + +int OSSL_trace_string(BIO *out, int text, int full, + const unsigned char *data, size_t size) +{ + unsigned char buf[OSSL_TRACE_STRING_MAX + 1]; + int len, i; + + if (!full && size > OSSL_TRACE_STRING_MAX) { + BIO_printf(out, "[len %zu limited to %d]: ", + size, OSSL_TRACE_STRING_MAX); + len = OSSL_TRACE_STRING_MAX; + } else { + len = (int)size; + } + if (!text) { /* mask control characters while preserving newlines */ + for (i = 0; i < len; i++, data++) + buf[i] = (char)*data != '\n' && ossl_iscntrl((int)*data) + ? ' ' : *data; + if (len == 0 || data[-1] != '\n') + buf[len++] = '\n'; + data = buf; + } + return BIO_printf(out, "%.*s", len, data); +} diff --git a/doc/man3/OSSL_trace_enabled.pod b/doc/man3/OSSL_trace_enabled.pod index 58db2cc9fd..1cc45b11c7 100644 --- a/doc/man3/OSSL_trace_enabled.pod +++ b/doc/man3/OSSL_trace_enabled.pod @@ -7,6 +7,7 @@ OSSL_TRACE_BEGIN, OSSL_TRACE_END, OSSL_TRACE_CANCEL, OSSL_TRACE, OSSL_TRACE1, OSSL_TRACE2, OSSL_TRACE3, OSSL_TRACE4, OSSL_TRACE5, OSSL_TRACE6, OSSL_TRACE7, OSSL_TRACE8, OSSL_TRACE9, OSSL_TRACEV, +OSSL_TRACE_STRING, OSSL_TRACE_STRING_MAX, OSSL_trace_string, OSSL_TRACE_ENABLED - OpenSSL Tracing API @@ -38,6 +39,11 @@ OSSL_TRACE_ENABLED OSSL_TRACE2(category, format, arg1, arg2) ... OSSL_TRACE9(category, format, arg1, ..., arg9) + OSSL_TRACE_STRING(category, text, full, data, len) + + #define OSSL_TRACE_STRING_MAX 80 + int OSSL_trace_string(BIO *out, int text, int full, + const unsigned char *data, size_t size); /* check whether a trace category is enabled */ if (OSSL_TRACE_ENABLED(category)) { @@ -102,6 +108,12 @@ is I<mandatory>. The result of trying to produce tracing output outside of such sections is undefined. +OSSL_trace_string() outputs I<data> of length I<size> as a string on BIO I<out>. +If I<text> is 0, the function masks any included control characters apart from +newlines and makes sure for nonempty input that the output ends with a newline. +Unless I<full> is nonzero, the length is limited (with a suitable warning) +to B<OSSL_TRACE_STRING_MAX> characters, which currently is 80. + =head2 Macros There are a number of convenience macros defined, to make tracing @@ -165,13 +177,22 @@ printf-style trace output with n format field arguments (n=1,...,9). It expands to: OSSL_TRACE_BEGIN(category) { - BIO_printf(trc_out, format, arg1, ..., argN) + BIO_printf(trc_out, format, arg1, ..., argN); } OSSL_TRACE_END(category) Internally, all one-shot macros are implemented using a generic OSSL_TRACEV() macro, since C90 does not support variadic macros. This helper macro has a rather weird synopsis and should not be used directly. +The macro call C<OSSL_TRACE_STRING(category, text, full, data, len)> +outputs I<data> of length I<size> as a string +if tracing for the given I<category> is enabled. +It expands to: + + OSSL_TRACE_BEGIN(category) { + OSSL_trace_string(trc_out, text, full, data, len); + } OSSL_TRACE_END(category) + The OSSL_TRACE_ENABLED() macro can be used to conditionally execute some code only if a specific trace category is enabled. In some situations this is simpler than entering a trace section using @@ -279,6 +300,8 @@ operational and enabled, otherwise 0. OSSL_trace_begin() returns a B<BIO> pointer if the given I<type> is enabled, otherwise NULL. +OSSL_trace_string() returns the number of characters emitted, or -1 on error. + =head1 SEE ALSO L<OSSL_trace_set_channel(3)>, L<OSSL_trace_set_callback(3)> @@ -287,6 +310,9 @@ L<OSSL_trace_set_channel(3)>, L<OSSL_trace_set_callback(3)> The OpenSSL Tracing API was added in OpenSSL 3.0. +OSSL_TRACE_STRING(), OSSL_TRACE_STRING_MAX, and OSSL_trace_string +were added in OpenSSL 3.2. + =head1 COPYRIGHT Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/openssl/trace.h b/include/openssl/trace.h index 23f90c65aa..dbd2ffdf5e 100644 --- a/include/openssl/trace.h +++ b/include/openssl/trace.h @@ -305,6 +305,14 @@ void OSSL_trace_end(int category, BIO *channel); # define OSSL_TRACE9(category, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ OSSL_TRACEV(category, (trc_out, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)) +#define OSSL_TRACE_STRING_MAX 80 +int OSSL_trace_string(BIO *out, int text, int full, + const unsigned char *data, size_t size); +#define OSSL_TRACE_STRING(category, text, full, data, len) \ + OSSL_TRACE_BEGIN(category) { \ + OSSL_trace_string(trc_out, text, full, data, len); \ + } OSSL_TRACE_END(category) + # ifdef __cplusplus } # endif diff --git a/test/trace_api_test.c b/test/trace_api_test.c index ba9ba226c3..15b5805e64 100644 --- a/test/trace_api_test.c +++ b/test/trace_api_test.c @@ -65,18 +65,45 @@ static int test_trace_categories(void) } #ifndef OPENSSL_NO_TRACE -static void put_trace_output(void) + +# define OSSL_START "xyz-" +# define OSSL_HELLO "Hello World\n" +/* OSSL_STR80 must have length OSSL_TRACE_STRING_MAX */ +# define OSSL_STR80 "1234567890123456789012345678901234567890123456789012345678901234567890123456789\n" +# define OSSL_STR81 (OSSL_STR80"x") +# define OSSL_CTRL "A\xfe\nB" +# define OSSL_MASKED "A \nB" +# define OSSL_BYE "Good Bye Universe\n" +# define OSSL_END "-abc" + +# define trace_string(text, full, str) \ + OSSL_trace_string(trc_out, text, full, (unsigned char *)(str), strlen(str)) + +static int put_trace_output(void) { + int res = 1; + OSSL_TRACE_BEGIN(HTTP) { - BIO_printf(trc_out, "Hello World\n"); - BIO_printf(trc_out, "Good Bye Universe\n"); + res = TEST_int_eq(BIO_printf(trc_out, OSSL_HELLO), strlen(OSSL_HELLO)) + + TEST_int_eq(trace_string(0, 0, OSSL_STR80), strlen(OSSL_STR80)) + + TEST_int_eq(trace_string(0, 0, OSSL_STR81), strlen(OSSL_STR80)) + + TEST_int_eq(trace_string(1, 1, OSSL_CTRL), strlen(OSSL_CTRL)) + + TEST_int_eq(trace_string(0, 1, OSSL_MASKED), strlen(OSSL_MASKED) + + 1) /* newline added */ + + TEST_int_eq(BIO_printf(trc_out, OSSL_BYE), strlen(OSSL_BYE)) + == 6; + /* not using '&&' but '+' to catch potentially multiple test failures */ } OSSL_TRACE_END(HTTP); + return res; } static int test_trace_channel(void) { - static const char expected[] = "xyz-\nHello World\nGood Bye Universe\n-abc\n"; - static const char expected_len = sizeof(expected) - 1; + static const char expected[] = + OSSL_START"\n" OSSL_HELLO + OSSL_STR80 "[len 81 limited to 80]: "OSSL_STR80 + OSSL_CTRL OSSL_MASKED"\n" OSSL_BYE OSSL_END"\n"; + static const size_t expected_len = sizeof(expected) - 1; BIO *bio = NULL; char *p_buf = NULL; long len = 0; @@ -86,28 +113,29 @@ static int test_trace_channel(void) if (!TEST_ptr(bio)) goto end; - if (!TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_HTTP, bio), 1)) + if (!TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_HTTP, bio), 1)) { + BIO_free(bio); goto end; + } if (!TEST_true(OSSL_trace_enabled(OSSL_TRACE_CATEGORY_HTTP))) goto end; - if (!TEST_int_eq(OSSL_trace_set_prefix(OSSL_TRACE_CATEGORY_HTTP, "xyz-"), 1)) + if (!TEST_int_eq(OSSL_trace_set_prefix(OSSL_TRACE_CATEGORY_HTTP, + OSSL_START), 1)) goto end; - if (!TEST_int_eq(OSSL_trace_set_suffix(OSSL_TRACE_CATEGORY_HTTP, "-abc"), 1)) + if (!TEST_int_eq(OSSL_trace_set_suffix(OSSL_TRACE_CATEGORY_HTTP, + OSSL_END), 1)) goto end; - put_trace_output(); + ret = put_trace_output(); len = BIO_get_mem_data(bio, &p_buf); if (!TEST_strn2_eq(p_buf, len, expected, expected_len)) - goto end; - if (!TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_HTTP, NULL), 1)) - goto end; - bio = NULL; + ret = 0; + ret = TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_HTTP, NULL), 1) + && ret; - ret = 1; end: - BIO_free(bio); return ret; } diff --git a/util/libcrypto.num b/util/libcrypto.num index 905272f7e0..3dcfc7dd52 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5433,6 +5433,7 @@ RAND_set0_private ? 3_1_0 EXIST::FUNCTION: BN_are_coprime ? 3_1_0 EXIST::FUNCTION: X509_PUBKEY_set0_public_key ? 3_2_0 EXIST::FUNCTION: OSSL_STACK_OF_X509_free ? 3_2_0 EXIST::FUNCTION: +OSSL_trace_string ? 3_2_0 EXIST::FUNCTION: EVP_MD_CTX_dup ? 3_2_0 EXIST::FUNCTION: EVP_CIPHER_CTX_dup ? 3_2_0 EXIST::FUNCTION: BN_signed_bin2bn ? 3_2_0 EXIST::FUNCTION: |