X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Ftrace.c;h=ecfc6d4e3101e59a778098c6544207b23513504b;hb=792ea008af17238d2af91301241973dc4f4f544c;hp=b42f1d9a2288313caf06e20296202aa51d489a12;hpb=5c64173586386a7c73e6431166c96eb43ae0baa2;p=oweals%2Fopenssl.git diff --git a/crypto/trace.c b/crypto/trace.c index b42f1d9a22..ecfc6d4e31 100644 --- a/crypto/trace.c +++ b/crypto/trace.c @@ -65,7 +65,7 @@ static int trace_write(BIO *channel, const char *buf, size_t num, size_t *written) { struct trace_data_st *ctx = BIO_get_data(channel); - size_t cnt = ctx->callback(buf, num, ctx->category, OSSL_TRACE_CTRL_DURING, + size_t cnt = ctx->callback(buf, num, ctx->category, OSSL_TRACE_CTRL_WRITE, ctx->data); *written = cnt; @@ -119,10 +119,19 @@ struct trace_category_st { #define TRACE_CATEGORY_(name) { #name, OSSL_TRACE_CATEGORY_##name } static const struct trace_category_st trace_categories[] = { - TRACE_CATEGORY_(ANY), + TRACE_CATEGORY_(ALL), + TRACE_CATEGORY_(TRACE), TRACE_CATEGORY_(INIT), TRACE_CATEGORY_(TLS), TRACE_CATEGORY_(TLS_CIPHER), + TRACE_CATEGORY_(CONF), + TRACE_CATEGORY_(ENGINE_TABLE), + 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) @@ -149,7 +158,7 @@ int OSSL_trace_get_category_num(const char *name) /* We use one trace channel for each trace category */ static struct { - enum { t_channel, t_callback } type; + enum { SIMPLE_CHANNEL, CALLBACK_CHANNEL } type; BIO *bio; char *prefix; char *suffix; @@ -159,24 +168,159 @@ 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, int type, 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].type = 0; + trace_channels[category].bio = NULL; + } + + /* Before running callbacks are done, set new data where appropriate */ + if (channel != NULL && *channel != NULL) { + trace_channels[category].type = type; + 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, 0, &channel, &prefix, &suffix, + trace_attach_cb, trace_detach_cb); + } + set_trace_data(OSSL_TRACE_CATEGORY_TRACE, 0, &channel, + &prefix, &suffix, + trace_attach_cb, trace_detach_cb); CRYPTO_THREAD_lock_free(trace_lock); #endif } @@ -184,62 +328,62 @@ 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 (category >= 0 && category < OSSL_TRACE_CATEGORY_NUM) + return set_trace_data(category, SIMPLE_CHANNEL, &channel, NULL, NULL, + trace_attach_cb, trace_detach_cb); +#endif + return 0; +} - if (prev_channel != NULL) { - BIO_free(prev_channel); - trace_channels[category].bio = NULL; +#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; } - - if (channel == NULL) - return 1; /* Done */ - - trace_channels[category].bio = channel; - trace_channels[category].type = t_channel; - return 1; - - err: -#endif - - return 0; } +#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) - goto err; + if (category < 0 || category >= OSSL_TRACE_CATEGORY_NUM) + return 0; - 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, CALLBACK_CHANNEL, &channel, NULL, NULL, + trace_attach_w_callback_cb, trace_detach_cb)) + goto err; return 1; @@ -254,54 +398,20 @@ int OSSL_trace_set_callback(int category, OSSL_trace_cb callback, void *data) 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; - } - - 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: + if (category >= 0 && category < OSSL_TRACE_CATEGORY_NUM) + return set_trace_data(category, 0, NULL, &prefix, NULL, + trace_attach_cb, trace_detach_cb); #endif - return 0; } int OSSL_trace_set_suffix(int category, const char *suffix) { #ifndef OPENSSL_NO_TRACE - char *curr_suffix = trace_channels[category].suffix; - - 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: + if (category >= 0 && category < OSSL_TRACE_CATEGORY_NUM) + return set_trace_data(category, 0, NULL, NULL, &suffix, + trace_attach_cb, trace_detach_cb); #endif - return 0; } @@ -312,7 +422,7 @@ static int ossl_trace_get_category(int category) return -1; if (trace_channels[category].bio != NULL) return category; - return OSSL_TRACE_CATEGORY_ANY; + return OSSL_TRACE_CATEGORY_ALL; } #endif @@ -321,7 +431,8 @@ int OSSL_trace_enabled(int category) int ret = 0; #ifndef OPENSSL_NO_TRACE category = ossl_trace_get_category(category); - ret = trace_channels[category].bio != NULL; + if (category >= 0) + ret = trace_channels[category].bio != NULL; #endif return ret; } @@ -333,6 +444,9 @@ BIO *OSSL_trace_begin(int category) char *prefix = NULL; category = ossl_trace_get_category(category); + if (category < 0) + return NULL; + channel = trace_channels[category].bio; prefix = trace_channels[category].prefix; @@ -340,13 +454,13 @@ BIO *OSSL_trace_begin(int category) CRYPTO_THREAD_write_lock(trace_lock); current_channel = channel; switch (trace_channels[category].type) { - case t_channel: + case SIMPLE_CHANNEL: if (prefix != NULL) { (void)BIO_puts(channel, prefix); (void)BIO_puts(channel, "\n"); } break; - case t_callback: + case CALLBACK_CHANNEL: (void)BIO_ctrl(channel, OSSL_TRACE_CTRL_BEGIN, prefix == NULL ? 0 : strlen(prefix), prefix); break; @@ -367,13 +481,13 @@ void OSSL_trace_end(int category, BIO * channel) && ossl_assert(channel == current_channel)) { (void)BIO_flush(channel); switch (trace_channels[category].type) { - case t_channel: + case SIMPLE_CHANNEL: if (suffix != NULL) { (void)BIO_puts(channel, suffix); (void)BIO_puts(channel, "\n"); } break; - case t_callback: + case CALLBACK_CHANNEL: (void)BIO_ctrl(channel, OSSL_TRACE_CTRL_END, suffix == NULL ? 0 : strlen(suffix), suffix); break;