X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Ftrace.c;h=2319f5ff1b8d67d25298844d0179a5125336961d;hp=8020a58e68746733085fdb68df0cebfbcb91b2c7;hb=e474a286f55966cd14b96334a621e53df62d3ef6;hpb=b9ce85f631cf376cd781fd3dfdc80e927d88ee77 diff --git a/crypto/trace.c b/crypto/trace.c index 8020a58e68..2319f5ff1b 100644 --- a/crypto/trace.c +++ b/crypto/trace.c @@ -120,6 +120,7 @@ struct trace_category_st { static const struct trace_category_st trace_categories[] = { TRACE_CATEGORY_(ANY), + TRACE_CATEGORY_(TRACE), TRACE_CATEGORY_(INIT), TRACE_CATEGORY_(TLS), TRACE_CATEGORY_(TLS_CIPHER), @@ -128,7 +129,9 @@ static const struct trace_category_st trace_categories[] = { TRACE_CATEGORY_(ENGINE_REF_COUNT), TRACE_CATEGORY_(PKCS5V2), TRACE_CATEGORY_(PKCS12_KEYGEN), + TRACE_CATEGORY_(PKCS12_DECRYPT), TRACE_CATEGORY_(X509V3_POLICY), + TRACE_CATEGORY_(BN_CTX), }; const char *OSSL_trace_get_category_name(int num) @@ -165,24 +168,156 @@ static struct { #endif +#ifndef OPENSSL_NO_TRACE + +enum { + CHANNEL, + PREFIX, + SUFFIX +}; + +static int trace_attach_cb(int category, int type, const void *data) +{ + switch (type) { + case CHANNEL: + OSSL_TRACE2(TRACE, "Attach channel %p to category '%s'\n", + data, trace_categories[category].name); + break; + case PREFIX: + OSSL_TRACE2(TRACE, "Attach prefix \"%s\" to category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + case SUFFIX: + OSSL_TRACE2(TRACE, "Attach suffix \"%s\" to category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + default: /* No clue */ + break; + } + return 1; +} + +static int trace_detach_cb(int category, int type, const void *data) +{ + switch (type) { + case CHANNEL: + OSSL_TRACE2(TRACE, "Detach channel %p from category '%s'\n", + data, trace_categories[category].name); + break; + case PREFIX: + OSSL_TRACE2(TRACE, "Detach prefix \"%s\" from category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + case SUFFIX: + OSSL_TRACE2(TRACE, "Detach suffix \"%s\" from category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + default: /* No clue */ + break; + } + return 1; +} + +static int set_trace_data(int category, BIO **channel, + const char **prefix, const char **suffix, + int (*attach_cb)(int, int, const void *), + int (*detach_cb)(int, int, const void *)) +{ + BIO *curr_channel = trace_channels[category].bio; + char *curr_prefix = trace_channels[category].prefix; + char *curr_suffix = trace_channels[category].suffix; + + /* Make sure to run the detach callback first on all data */ + if (prefix != NULL && curr_prefix != NULL) { + detach_cb(category, PREFIX, curr_prefix); + } + + if (suffix != NULL && curr_suffix != NULL) { + detach_cb(category, SUFFIX, curr_suffix); + } + + if (channel != NULL && curr_channel != NULL) { + detach_cb(category, CHANNEL, curr_channel); + } + + /* After detach callbacks are done, clear data where appropriate */ + if (prefix != NULL && curr_prefix != NULL) { + OPENSSL_free(curr_prefix); + trace_channels[category].prefix = NULL; + } + + if (suffix != NULL && curr_suffix != NULL) { + OPENSSL_free(curr_suffix); + trace_channels[category].suffix = NULL; + } + + if (channel != NULL && curr_channel != NULL) { + BIO_free(curr_channel); + trace_channels[category].bio = NULL; + } + + /* Before running callbacks are done, set new data where appropriate */ + if (channel != NULL && *channel != NULL) { + trace_channels[category].bio = *channel; + } + + if (prefix != NULL && *prefix != NULL) { + if ((curr_prefix = OPENSSL_strdup(*prefix)) == NULL) + return 0; + trace_channels[category].prefix = curr_prefix; + } + + if (suffix != NULL && *suffix != NULL) { + if ((curr_suffix = OPENSSL_strdup(*suffix)) == NULL) + return 0; + trace_channels[category].suffix = curr_suffix; + } + + /* Finally, run the attach callback on the new data */ + if (channel != NULL && *channel != NULL) { + attach_cb(category, CHANNEL, *channel); + } + + if (prefix != NULL && *prefix != NULL) { + attach_cb(category, PREFIX, *prefix); + } + + if (suffix != NULL && *suffix != NULL) { + attach_cb(category, SUFFIX, *suffix); + } + + return 1; +} +#endif + int ossl_trace_init(void) { #ifndef OPENSSL_NO_TRACE trace_lock = CRYPTO_THREAD_lock_new(); - if (trace_lock != NULL) - return 1; + if (trace_lock == NULL) + return 0; #endif - return 0; + return 1; } void ossl_trace_cleanup(void) { #ifndef OPENSSL_NO_TRACE int category; - - for (category = 0; category < OSSL_TRACE_CATEGORY_NUM; category++) - OSSL_trace_set_channel(category, NULL); + BIO *channel = NULL; + const char *prefix = NULL; + const char *suffix = NULL; + + for (category = 0; category < OSSL_TRACE_CATEGORY_NUM; category++) { + /* We force the TRACE category to be treated last */ + if (category == OSSL_TRACE_CATEGORY_TRACE) + continue; + set_trace_data(category, &channel, &prefix, &suffix, + trace_attach_cb, trace_detach_cb); + } + set_trace_data(OSSL_TRACE_CATEGORY_TRACE, &channel, &prefix, &suffix, + trace_attach_cb, trace_detach_cb); CRYPTO_THREAD_lock_free(trace_lock); #endif } @@ -190,125 +325,102 @@ void ossl_trace_cleanup(void) int OSSL_trace_set_channel(int category, BIO *channel) { #ifndef OPENSSL_NO_TRACE - BIO *prev_channel; - - if (category < 0 || category >= OSSL_TRACE_CATEGORY_NUM) - goto err; - - prev_channel = trace_channels[category].bio; - - if (prev_channel != NULL) { - BIO_free(prev_channel); - trace_channels[category].bio = NULL; - } - - if (channel == NULL) - return 1; /* Done */ + if (category < 0 || category >= OSSL_TRACE_CATEGORY_NUM + || !set_trace_data(category, &channel, NULL, NULL, + trace_attach_cb, trace_detach_cb)) + return 0; - trace_channels[category].bio = channel; trace_channels[category].type = t_channel; - - return 1; - - err: #endif + return 1; +} - return 0; +#ifndef OPENSSL_NO_TRACE +static int trace_attach_w_callback_cb(int category, int type, const void *data) +{ + switch (type) { + case CHANNEL: + OSSL_TRACE2(TRACE, + "Attach channel %p to category '%s' (with callback)\n", + data, trace_categories[category].name); + break; + case PREFIX: + OSSL_TRACE2(TRACE, "Attach prefix \"%s\" to category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + case SUFFIX: + OSSL_TRACE2(TRACE, "Attach suffix \"%s\" to category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + default: /* No clue */ + break; + } + return 1; } +#endif int OSSL_trace_set_callback(int category, OSSL_trace_cb callback, void *data) { #ifndef OPENSSL_NO_TRACE - BIO *channel = trace_channels[category].bio; + BIO *channel = NULL; struct trace_data_st *trace_data = NULL; - if (channel != NULL) { - BIO_free(channel); - trace_channels[category].bio = NULL; - } - - if (callback == NULL) - return 1; /* done */ - - channel = BIO_new(&trace_method); - if (channel == NULL) + if (category < 0 || category >= OSSL_TRACE_CATEGORY_NUM) goto err; - trace_data = OPENSSL_zalloc(sizeof(struct trace_data_st)); - if (trace_data == NULL) - goto err; + if (callback != NULL) { + if ((channel = BIO_new(&trace_method)) == NULL + || (trace_data = + OPENSSL_zalloc(sizeof(struct trace_data_st))) == NULL) + goto err; - trace_data->callback = callback; - trace_data->category = category; - trace_data->data = data; + trace_data->callback = callback; + trace_data->category = category; + trace_data->data = data; - BIO_set_data(channel, trace_data); + BIO_set_data(channel, trace_data); + } - trace_channels[category].bio = channel; - trace_channels[category].type = t_callback; + if (!set_trace_data(category, &channel, NULL, NULL, + trace_attach_w_callback_cb, trace_detach_cb)) + goto err; - return 1; + trace_channels[category].type = t_callback; + goto done; err: BIO_free(channel); OPENSSL_free(trace_data); -#endif - return 0; + done: +#endif + return 1; } int OSSL_trace_set_prefix(int category, const char *prefix) { -#ifndef OPENSSL_NO_TRACE - char *curr_prefix = trace_channels[category].prefix; - - if (curr_prefix != NULL) { - OPENSSL_free(curr_prefix); - trace_channels[category].prefix = NULL; - } + int rv = 1; - if (prefix == NULL) - return 1; /* Done */ - - curr_prefix = OPENSSL_strdup(prefix); - if (curr_prefix == NULL) - goto err; - - trace_channels[category].prefix = curr_prefix; - - return 1; - - err: +#ifndef OPENSSL_NO_TRACE + if (category >= 0 || category < OSSL_TRACE_CATEGORY_NUM) + return set_trace_data(category, NULL, &prefix, NULL, + trace_attach_cb, trace_detach_cb); + rv = 0; #endif - - return 0; + return rv; } int OSSL_trace_set_suffix(int category, const char *suffix) { -#ifndef OPENSSL_NO_TRACE - char *curr_suffix = trace_channels[category].suffix; + int rv = 1; - if (curr_suffix != NULL) { - OPENSSL_free(curr_suffix); - trace_channels[category].suffix = NULL; - } - - if (suffix == NULL) - return 1; /* done */ - - curr_suffix = OPENSSL_strdup(suffix); - if (curr_suffix == NULL) - goto err; - - trace_channels[category].suffix = curr_suffix; - - return 1; - - err: +#ifndef OPENSSL_NO_TRACE + if (category >= 0 || category < OSSL_TRACE_CATEGORY_NUM) + return set_trace_data(category, NULL, NULL, &suffix, + trace_attach_cb, trace_detach_cb); + rv = 0; #endif - - return 0; + return rv; } #ifndef OPENSSL_NO_TRACE