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