summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/trace.c25
-rw-r--r--doc/man3/OSSL_trace_enabled.pod28
-rw-r--r--include/openssl/trace.h8
-rw-r--r--test/trace_api_test.c58
-rw-r--r--util/libcrypto.num1
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: