xref: /freebsd-src/crypto/openssl/doc/man3/OSSL_trace_set_channel.pod (revision aa7957345732816fb0ba8308798d2f79f45597f9)
1b077aed3SPierre Pronchery=pod
2b077aed3SPierre Pronchery
3b077aed3SPierre Pronchery=for openssl foreign manual atexit(3)
4b077aed3SPierre Pronchery
5b077aed3SPierre Pronchery=head1 NAME
6b077aed3SPierre Pronchery
7b077aed3SPierre ProncheryOSSL_trace_set_channel, OSSL_trace_set_prefix, OSSL_trace_set_suffix,
8b077aed3SPierre ProncheryOSSL_trace_set_callback, OSSL_trace_cb - Enabling trace output
9b077aed3SPierre Pronchery
10b077aed3SPierre Pronchery=head1 SYNOPSIS
11b077aed3SPierre Pronchery
12b077aed3SPierre Pronchery #include <openssl/trace.h>
13b077aed3SPierre Pronchery
14b077aed3SPierre Pronchery typedef size_t (*OSSL_trace_cb)(const char *buf, size_t cnt,
15b077aed3SPierre Pronchery                                 int category, int cmd, void *data);
16b077aed3SPierre Pronchery
17b077aed3SPierre Pronchery void OSSL_trace_set_channel(int category, BIO *bio);
18b077aed3SPierre Pronchery void OSSL_trace_set_prefix(int category, const char *prefix);
19b077aed3SPierre Pronchery void OSSL_trace_set_suffix(int category, const char *suffix);
20b077aed3SPierre Pronchery void OSSL_trace_set_callback(int category, OSSL_trace_cb cb, void  *data);
21b077aed3SPierre Pronchery
22b077aed3SPierre Pronchery=head1 DESCRIPTION
23b077aed3SPierre Pronchery
24b077aed3SPierre ProncheryIf available (see L</NOTES> below), the application can request
25b077aed3SPierre Proncheryinternal trace output.
26b077aed3SPierre ProncheryThis output comes in form of free text for humans to read.
27b077aed3SPierre Pronchery
28b077aed3SPierre ProncheryThe trace output is divided into categories which can be
29b077aed3SPierre Proncheryenabled individually.
30b077aed3SPierre ProncheryEvery category can be enabled individually by attaching a so called
31b077aed3SPierre ProncheryI<trace channel> to it, which in the simplest case is just a BIO object
32b077aed3SPierre Proncheryto which the application can write the tracing output for this category.
33b077aed3SPierre ProncheryAlternatively, the application can provide a tracer callback in order to
34b077aed3SPierre Proncheryget more finegrained trace information. This callback will be wrapped
35b077aed3SPierre Proncheryinternally by a dedicated BIO object.
36b077aed3SPierre Pronchery
37b077aed3SPierre ProncheryFor the tracing code, both trace channel types are indistinguishable.
38b077aed3SPierre ProncheryThese are called a I<simple trace channel> and a I<callback trace channel>,
39b077aed3SPierre Proncheryrespectively.
40b077aed3SPierre Pronchery
41b077aed3SPierre Pronchery=head2 Functions
42b077aed3SPierre Pronchery
43b077aed3SPierre ProncheryOSSL_trace_set_channel() is used to enable the given trace C<category>
44b077aed3SPierre Proncheryby attaching the B<BIO> I<bio> object as (simple) trace channel.
45b077aed3SPierre ProncheryOn success the ownership of the BIO is transferred to the channel,
46b077aed3SPierre Proncheryso the caller must not free it directly.
47b077aed3SPierre Pronchery
48b077aed3SPierre ProncheryOSSL_trace_set_prefix() and OSSL_trace_set_suffix() can be used to add
49b077aed3SPierre Proncheryan extra line for each channel, to be output before and after group of
50b077aed3SPierre Proncherytracing output.
51*aa795734SPierre ProncheryWhat constitutes an output group is decided by the code that produces
52b077aed3SPierre Proncherythe output.
53b077aed3SPierre ProncheryThe lines given here are considered immutable; for more dynamic
54b077aed3SPierre Proncherytracing prefixes, consider setting a callback with
55b077aed3SPierre ProncheryOSSL_trace_set_callback() instead.
56b077aed3SPierre Pronchery
57b077aed3SPierre ProncheryOSSL_trace_set_callback() is used to enable the given trace
58b077aed3SPierre ProncheryI<category> by giving it the tracer callback I<cb> with the associated
59b077aed3SPierre Proncherydata I<data>, which will simply be passed through to I<cb> whenever
60b077aed3SPierre Proncheryit's called. The callback function is internally wrapped by a
61b077aed3SPierre Proncherydedicated BIO object, the so called I<callback trace channel>.
62b077aed3SPierre ProncheryThis should be used when it's desirable to do form the trace output to
63b077aed3SPierre Proncherysomething suitable for application needs where a prefix and suffix
64b077aed3SPierre Proncheryline aren't enough.
65b077aed3SPierre Pronchery
66b077aed3SPierre ProncheryOSSL_trace_set_channel() and OSSL_trace_set_callback() are mutually
67b077aed3SPierre Proncheryexclusive, calling one of them will clear whatever was set by the
68b077aed3SPierre Proncheryprevious call.
69b077aed3SPierre Pronchery
70b077aed3SPierre ProncheryCalling OSSL_trace_set_channel() with NULL for I<channel> or
71b077aed3SPierre ProncheryOSSL_trace_set_callback() with NULL for I<cb> disables tracing for
72b077aed3SPierre Proncherythe given I<category>.
73b077aed3SPierre Pronchery
74b077aed3SPierre Pronchery=head2 Trace callback
75b077aed3SPierre Pronchery
76b077aed3SPierre ProncheryThe tracer callback must return a B<size_t>, which must be zero on
77b077aed3SPierre Proncheryerror and otherwise return the number of bytes that were output.
78b077aed3SPierre ProncheryIt receives a text buffer I<buf> with I<cnt> bytes of text, as well as
79b077aed3SPierre Proncherythe I<category>, a control number I<cmd>, and the I<data> that was
80b077aed3SPierre Proncherypassed to OSSL_trace_set_callback().
81b077aed3SPierre Pronchery
82b077aed3SPierre ProncheryThe possible control numbers are:
83b077aed3SPierre Pronchery
84b077aed3SPierre Pronchery=over 4
85b077aed3SPierre Pronchery
86b077aed3SPierre Pronchery=item B<OSSL_TRACE_CTRL_BEGIN>
87b077aed3SPierre Pronchery
88b077aed3SPierre ProncheryThe callback is called from OSSL_trace_begin(), which gives the
89b077aed3SPierre Proncherycallback the possibility to output a dynamic starting line, or set a
90b077aed3SPierre Proncheryprefix that should be output at the beginning of each line, or
91b077aed3SPierre Proncherysomething other.
92b077aed3SPierre Pronchery
93b077aed3SPierre Pronchery=item B<OSSL_TRACE_CTRL_WRITE>
94b077aed3SPierre Pronchery
95b077aed3SPierre ProncheryThis callback is called whenever data is written to the BIO by some
96b077aed3SPierre Proncheryregular BIO output routine.
97b077aed3SPierre ProncheryAn arbitrary number of B<OSSL_TRACE_CTRL_WRITE> callbacks can occur
98b077aed3SPierre Proncheryinside a group marked by a pair of B<OSSL_TRACE_CTRL_BEGIN> and
99b077aed3SPierre ProncheryB<OSSL_TRACE_CTRL_END> calls, but never outside such a group.
100b077aed3SPierre Pronchery
101b077aed3SPierre Pronchery=item B<OSSL_TRACE_CTRL_END>
102b077aed3SPierre Pronchery
103b077aed3SPierre ProncheryThe callback is called from OSSL_trace_end(), which gives the callback
104b077aed3SPierre Proncherythe possibility to output a dynamic ending line, or reset the line
105b077aed3SPierre Proncheryprefix that was set with B<OSSL_TRACE_CTRL_BEGIN>, or something other.
106b077aed3SPierre Pronchery
107b077aed3SPierre Pronchery=back
108b077aed3SPierre Pronchery
109b077aed3SPierre Pronchery=head2 Trace categories
110b077aed3SPierre Pronchery
111b077aed3SPierre ProncheryThe trace categories are simple numbers available through macros.
112b077aed3SPierre Pronchery
113b077aed3SPierre Pronchery=over 4
114b077aed3SPierre Pronchery
115b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_TRACE>
116b077aed3SPierre Pronchery
117b077aed3SPierre ProncheryTraces the OpenSSL trace API itself.
118b077aed3SPierre Pronchery
119b077aed3SPierre ProncheryMore precisely, this will generate trace output any time a new
120b077aed3SPierre Proncherytrace hook is set.
121b077aed3SPierre Pronchery
122b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_INIT>
123b077aed3SPierre Pronchery
124b077aed3SPierre ProncheryTraces OpenSSL library initialization and cleanup.
125b077aed3SPierre Pronchery
126b077aed3SPierre ProncheryThis needs special care, as OpenSSL will do automatic cleanup after
127b077aed3SPierre Proncheryexit from C<main()>, and any tracing output done during this cleanup
128b077aed3SPierre Proncherywill be lost if the tracing channel or callback were cleaned away
129b077aed3SPierre Proncheryprematurely.
130b077aed3SPierre ProncheryA suggestion is to make such cleanup part of a function that's
131b077aed3SPierre Proncheryregistered very early with L<atexit(3)>.
132b077aed3SPierre Pronchery
133b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_TLS>
134b077aed3SPierre Pronchery
135b077aed3SPierre ProncheryTraces the TLS/SSL protocol.
136b077aed3SPierre Pronchery
137b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_TLS_CIPHER>
138b077aed3SPierre Pronchery
139b077aed3SPierre ProncheryTraces the ciphers used by the TLS/SSL protocol.
140b077aed3SPierre Pronchery
141b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_CONF>
142b077aed3SPierre Pronchery
143b077aed3SPierre ProncheryTraces details about the provider and engine configuration.
144b077aed3SPierre Pronchery
145b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_ENGINE_TABLE>
146b077aed3SPierre Pronchery
147b077aed3SPierre ProncheryTraces the ENGINE algorithm table selection.
148b077aed3SPierre Pronchery
149b077aed3SPierre ProncheryMore precisely, functions like ENGINE_get_pkey_asn1_meth_engine(),
150b077aed3SPierre ProncheryENGINE_get_pkey_meth_engine(), ENGINE_get_cipher_engine(),
151b077aed3SPierre ProncheryENGINE_get_digest_engine(), will generate trace summaries of the
152b077aed3SPierre Proncheryhandling of internal tables.
153b077aed3SPierre Pronchery
154b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_ENGINE_REF_COUNT>
155b077aed3SPierre Pronchery
156b077aed3SPierre ProncheryTraces the ENGINE reference counting.
157b077aed3SPierre Pronchery
158b077aed3SPierre ProncheryMore precisely, both reference counts in the ENGINE structure will be
159b077aed3SPierre Proncherymonitored with a line of trace output generated for each change.
160b077aed3SPierre Pronchery
161b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_PKCS5V2>
162b077aed3SPierre Pronchery
163b077aed3SPierre ProncheryTraces PKCS#5 v2 key generation.
164b077aed3SPierre Pronchery
165b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_PKCS12_KEYGEN>
166b077aed3SPierre Pronchery
167b077aed3SPierre ProncheryTraces PKCS#12 key generation.
168b077aed3SPierre Pronchery
169b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_PKCS12_DECRYPT>
170b077aed3SPierre Pronchery
171b077aed3SPierre ProncheryTraces PKCS#12 decryption.
172b077aed3SPierre Pronchery
173b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_X509V3_POLICY>
174b077aed3SPierre Pronchery
175b077aed3SPierre ProncheryTraces X509v3 policy processing.
176b077aed3SPierre Pronchery
177b077aed3SPierre ProncheryMore precisely, this generates the complete policy tree at various
178b077aed3SPierre Proncherypoint during evaluation.
179b077aed3SPierre Pronchery
180b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_BN_CTX>
181b077aed3SPierre Pronchery
182b077aed3SPierre ProncheryTraces BIGNUM context operations.
183b077aed3SPierre Pronchery
184b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_CMP>
185b077aed3SPierre Pronchery
186b077aed3SPierre ProncheryTraces CMP client and server activity.
187b077aed3SPierre Pronchery
188b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_STORE>
189b077aed3SPierre Pronchery
190b077aed3SPierre ProncheryTraces STORE operations.
191b077aed3SPierre Pronchery
192b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_DECODER>
193b077aed3SPierre Pronchery
194b077aed3SPierre ProncheryTraces decoder operations.
195b077aed3SPierre Pronchery
196b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_ENCODER>
197b077aed3SPierre Pronchery
198b077aed3SPierre ProncheryTraces encoder operations.
199b077aed3SPierre Pronchery
200b077aed3SPierre Pronchery=item B<OSSL_TRACE_CATEGORY_REF_COUNT>
201b077aed3SPierre Pronchery
202b077aed3SPierre ProncheryTraces decrementing certain ASN.1 structure references.
203b077aed3SPierre Pronchery
204b077aed3SPierre Pronchery=back
205b077aed3SPierre Pronchery
206b077aed3SPierre ProncheryThere is also B<OSSL_TRACE_CATEGORY_ALL>, which works as a fallback
207b077aed3SPierre Proncheryand can be used to get I<all> trace output.
208b077aed3SPierre Pronchery
209b077aed3SPierre ProncheryNote, however, that in this case all trace output will effectively be
210b077aed3SPierre Proncheryassociated with the 'ALL' category, which is undesirable if the
211b077aed3SPierre Proncheryapplication intends to include the category name in the trace output.
212b077aed3SPierre ProncheryIn this case it is better to register separate channels for each
213b077aed3SPierre Proncherytrace category instead.
214b077aed3SPierre Pronchery
215b077aed3SPierre Pronchery=head1 RETURN VALUES
216b077aed3SPierre Pronchery
217b077aed3SPierre ProncheryOSSL_trace_set_channel(), OSSL_trace_set_prefix(),
218b077aed3SPierre ProncheryOSSL_trace_set_suffix(), and OSSL_trace_set_callback() return 1 on
219b077aed3SPierre Proncherysuccess, or 0 on failure.
220b077aed3SPierre Pronchery
221b077aed3SPierre Pronchery=head1 EXAMPLES
222b077aed3SPierre Pronchery
223b077aed3SPierre ProncheryIn all examples below, the trace producing code is assumed to be
224b077aed3SPierre Proncherythe following:
225b077aed3SPierre Pronchery
226b077aed3SPierre Pronchery int foo = 42;
227b077aed3SPierre Pronchery const char bar[] = { 0,  1,  2,  3,  4,  5,  6,  7,
228b077aed3SPierre Pronchery                      8,  9, 10, 11, 12, 13, 14, 15 };
229b077aed3SPierre Pronchery
230b077aed3SPierre Pronchery OSSL_TRACE_BEGIN(TLS) {
231b077aed3SPierre Pronchery     BIO_puts(trc_out, "foo: ");
232b077aed3SPierre Pronchery     BIO_printf(trc_out, "%d\n", foo);
233b077aed3SPierre Pronchery     BIO_dump(trc_out, bar, sizeof(bar));
234b077aed3SPierre Pronchery } OSSL_TRACE_END(TLS);
235b077aed3SPierre Pronchery
236b077aed3SPierre Pronchery=head2 Simple example
237b077aed3SPierre Pronchery
238b077aed3SPierre ProncheryAn example with just a channel and constant prefix / suffix.
239b077aed3SPierre Pronchery
240b077aed3SPierre Pronchery int main(int argc, char *argv[])
241b077aed3SPierre Pronchery {
242b077aed3SPierre Pronchery     BIO *err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
243b077aed3SPierre Pronchery     OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_SSL, err);
244b077aed3SPierre Pronchery     OSSL_trace_set_prefix(OSSL_TRACE_CATEGORY_SSL, "BEGIN TRACE[TLS]");
245b077aed3SPierre Pronchery     OSSL_trace_set_suffix(OSSL_TRACE_CATEGORY_SSL, "END TRACE[TLS]");
246b077aed3SPierre Pronchery
247b077aed3SPierre Pronchery     /* ... work ... */
248b077aed3SPierre Pronchery }
249b077aed3SPierre Pronchery
250b077aed3SPierre ProncheryWhen the trace producing code above is performed, this will be output
251b077aed3SPierre Proncheryon standard error:
252b077aed3SPierre Pronchery
253b077aed3SPierre Pronchery BEGIN TRACE[TLS]
254b077aed3SPierre Pronchery foo: 42
255b077aed3SPierre Pronchery 0000 - 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f   ................
256b077aed3SPierre Pronchery END TRACE[TLS]
257b077aed3SPierre Pronchery
258b077aed3SPierre Pronchery=head2 Advanced example
259b077aed3SPierre Pronchery
260b077aed3SPierre ProncheryThis example uses the callback, and depends on pthreads functionality.
261b077aed3SPierre Pronchery
262b077aed3SPierre Pronchery static size_t cb(const char *buf, size_t cnt,
263b077aed3SPierre Pronchery                 int category, int cmd, void *vdata)
264b077aed3SPierre Pronchery {
265b077aed3SPierre Pronchery     BIO *bio = vdata;
266b077aed3SPierre Pronchery     const char *label = NULL;
267b077aed3SPierre Pronchery
268b077aed3SPierre Pronchery     switch (cmd) {
269b077aed3SPierre Pronchery     case OSSL_TRACE_CTRL_BEGIN:
270b077aed3SPierre Pronchery         label = "BEGIN";
271b077aed3SPierre Pronchery         break;
272b077aed3SPierre Pronchery     case OSSL_TRACE_CTRL_END:
273b077aed3SPierre Pronchery         label = "END";
274b077aed3SPierre Pronchery         break;
275b077aed3SPierre Pronchery     }
276b077aed3SPierre Pronchery
277b077aed3SPierre Pronchery     if (label != NULL) {
278b077aed3SPierre Pronchery         union {
279b077aed3SPierre Pronchery             pthread_t tid;
280b077aed3SPierre Pronchery             unsigned long ltid;
281b077aed3SPierre Pronchery         } tid;
282b077aed3SPierre Pronchery
283b077aed3SPierre Pronchery         tid.tid = pthread_self();
284b077aed3SPierre Pronchery         BIO_printf(bio, "%s TRACE[%s]:%lx\n",
285b077aed3SPierre Pronchery                    label, OSSL_trace_get_category_name(category), tid.ltid);
286b077aed3SPierre Pronchery     }
287b077aed3SPierre Pronchery     return (size_t)BIO_puts(bio, buf);
288b077aed3SPierre Pronchery }
289b077aed3SPierre Pronchery
290b077aed3SPierre Pronchery int main(int argc, char *argv[])
291b077aed3SPierre Pronchery {
292b077aed3SPierre Pronchery     BIO *err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
293b077aed3SPierre Pronchery     OSSL_trace_set_callback(OSSL_TRACE_CATEGORY_SSL, cb, err);
294b077aed3SPierre Pronchery
295b077aed3SPierre Pronchery     /* ... work ... */
296b077aed3SPierre Pronchery }
297b077aed3SPierre Pronchery
298b077aed3SPierre ProncheryThe output is almost the same as for the simple example above.
299b077aed3SPierre Pronchery
300b077aed3SPierre Pronchery BEGIN TRACE[TLS]:7f9eb0193b80
301b077aed3SPierre Pronchery foo: 42
302b077aed3SPierre Pronchery 0000 - 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f   ................
303b077aed3SPierre Pronchery END TRACE[TLS]:7f9eb0193b80
304b077aed3SPierre Pronchery
305b077aed3SPierre Pronchery=head1 NOTES
306b077aed3SPierre Pronchery
307b077aed3SPierre Pronchery=head2 Configure Tracing
308b077aed3SPierre Pronchery
309b077aed3SPierre ProncheryBy default, the OpenSSL library is built with tracing disabled. To
310b077aed3SPierre Proncheryuse the tracing functionality documented here, it is therefore
311b077aed3SPierre Proncherynecessary to configure and build OpenSSL with the 'enable-trace' option.
312b077aed3SPierre Pronchery
313b077aed3SPierre ProncheryWhen the library is built with tracing disabled, the macro
314b077aed3SPierre ProncheryB<OPENSSL_NO_TRACE> is defined in F<< <openssl/opensslconf.h> >> and all
315b077aed3SPierre Proncheryfunctions described here are inoperational, i.e. will do nothing.
316b077aed3SPierre Pronchery
317b077aed3SPierre Pronchery=head1 HISTORY
318b077aed3SPierre Pronchery
319b077aed3SPierre ProncheryOSSL_trace_set_channel(), OSSL_trace_set_prefix(),
320b077aed3SPierre ProncheryOSSL_trace_set_suffix(), and OSSL_trace_set_callback() were all added
321b077aed3SPierre Proncheryin OpenSSL 3.0.
322b077aed3SPierre Pronchery
323b077aed3SPierre Pronchery=head1 COPYRIGHT
324b077aed3SPierre Pronchery
325b077aed3SPierre ProncheryCopyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
326b077aed3SPierre Pronchery
327b077aed3SPierre ProncheryLicensed under the Apache License 2.0 (the "License").  You may not use
328b077aed3SPierre Proncherythis file except in compliance with the License.  You can obtain a copy
329b077aed3SPierre Proncheryin the file LICENSE in the source distribution or at
330b077aed3SPierre ProncheryL<https://www.openssl.org/source/license.html>.
331b077aed3SPierre Pronchery
332b077aed3SPierre Pronchery=cut
333