From: Dr. David von Oheimb Date: Fri, 13 Dec 2019 18:50:20 +0000 (+0100) Subject: improve CMP logging according to comments on CMP chunk 7 preview X-Git-Tag: openssl-3.0.0-alpha1~456 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=ebf3006917e0e968af4a5d5c2c6379c5b866f801;p=oweals%2Fopenssl.git improve CMP logging according to comments on CMP chunk 7 preview in particular: consolidate documentation of CMP logging and error reporting functions fix compilation problem with clang on some platforms rename OSSL_CMP_log etc. to ossl_cmp_log etc. since these macros are CMP-internal move chopping of trailing separator to ossl_cmp_add_error_txt(), also fix handling of leading separator internalize X509_print_ex_brief() as x509_print_ex_brief() Reviewed-by: Matt Caswell Reviewed-by: Bernd Edlinger (Merged from https://github.com/openssl/openssl/pull/10620) --- diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c index fc89ea6bc8..12492336ef 100644 --- a/crypto/cmp/cmp_ctx.c +++ b/crypto/cmp/cmp_ctx.c @@ -301,7 +301,7 @@ static size_t ossl_cmp_log_trace_cb(const char *buf, size_t cnt, int category, int cmd, void *vdata) { OSSL_CMP_CTX *ctx = vdata; - const char *prefix_msg; + const char *msg; OSSL_CMP_severity level = -1; char *func = NULL; char *file = NULL; @@ -312,14 +312,14 @@ static size_t ossl_cmp_log_trace_cb(const char *buf, size_t cnt, if (ctx->log_cb == NULL) return 1; /* silently drop message */ - prefix_msg = ossl_cmp_log_parse_metadata(buf, &level, &func, &file, &line); + msg = ossl_cmp_log_parse_metadata(buf, &level, &func, &file, &line); if (level > ctx->log_verbosity) /* excludes the case level is unknown */ goto end; /* suppress output since severity is not sufficient */ if (!ctx->log_cb(func != NULL ? func : "(no func)", file != NULL ? file : "(no file)", - line, level, prefix_msg)) + line, level, msg)) cnt = 0; end: @@ -329,6 +329,57 @@ static size_t ossl_cmp_log_trace_cb(const char *buf, size_t cnt, } #endif +/* Print CMP log messages (i.e., diagnostic info) via the log cb of the ctx */ +int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, + const char *func, const char *file, int line, + const char *level_str, const char *format, ...) +{ + va_list args; + char hugebuf[1024 * 2]; + int res = 0; + + if (ctx == NULL || ctx->log_cb == NULL) + return 1; /* silently drop message */ + + if (level > ctx->log_verbosity) /* excludes the case level is unknown */ + return 1; /* suppress output since severity is not sufficient */ + + if (format == NULL) + return 0; + + va_start(args, format); + + if (func == NULL) + func = "(unset function name)"; + if (file == NULL) + file = "(unset file name)"; + if (level_str == NULL) + level_str = "(unset level string)"; + +#ifndef OPENSSL_NO_TRACE + if (OSSL_TRACE_ENABLED(CMP)) { + OSSL_TRACE_BEGIN(CMP) { + int printed = + BIO_snprintf(hugebuf, sizeof(hugebuf), + "%s:%s:%d:" OSSL_CMP_LOG_PREFIX "%s: ", + func, file, line, level_str); + if (printed > 0 && (size_t)printed < sizeof(hugebuf)) { + if (BIO_vsnprintf(hugebuf + printed, + sizeof(hugebuf) - printed, format, args) > 0) + res = BIO_puts(trc_out, hugebuf) > 0; + } + } OSSL_TRACE_END(CMP); + } +#else /* compensate for disabled trace API */ + { + if (BIO_vsnprintf(hugebuf, sizeof(hugebuf), format, args) > 0) + res = ctx->log_cb(func, file, line, level, hugebuf); + } +#endif + va_end(args); + return res; +} + /* * Set a callback function for error reporting and logging messages. * Returns 1 on success, 0 on error @@ -768,7 +819,7 @@ int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx, * returns 1 on success, 0 on error */ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx, - const ASN1_OCTET_STRING *nonce) + const ASN1_OCTET_STRING *nonce) { if (!ossl_assert(ctx != NULL)) return 0; diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h index f705cb24be..f36928bdf1 100644 --- a/crypto/cmp/cmp_local.h +++ b/crypto/cmp/cmp_local.h @@ -718,6 +718,31 @@ int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert); /* from cmp_ctx.c */ +int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, + const char *func, const char *file, int line, + const char *level_str, const char *format, ...); +# define ossl_cmp_log(level, ctx, msg) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, "%s", msg) +# define ossl_cmp_log1(level, ctx, fmt, arg1) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, fmt, arg1) +# define ossl_cmp_log2(level, ctx, fmt, arg1, arg2) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, fmt, arg1, arg2) +# define ossl_cmp_log3(level, ctx, fmt, arg1, arg2, arg3) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, fmt, arg1, arg2, arg3) +# define ossl_cmp_log4(level, ctx, fmt, arg1, arg2, arg3, arg4) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, fmt, arg1, arg2, arg3, arg4) +# define OSSL_CMP_LOG_ERROR OSSL_CMP_LOG_ERR +# define OSSL_CMP_LOG_WARN OSSL_CMP_LOG_WARNING +# define ossl_cmp_alert(ctx, msg) ossl_cmp_log(ALERT, ctx, msg) +# define ossl_cmp_err(ctx, msg) ossl_cmp_log(ERROR, ctx, msg) +# define ossl_cmp_warn(ctx, msg) ossl_cmp_log(WARN, ctx, msg) +# define ossl_cmp_info(ctx, msg) ossl_cmp_log(INFO, ctx, msg) +# define ossl_cmp_debug(ctx, msg) ossl_cmp_log(DEBUG, ctx, msg) int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert); int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status); int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx, diff --git a/crypto/cmp/cmp_util.c b/crypto/cmp/cmp_util.c index 0390c23e66..168bb854d1 100644 --- a/crypto/cmp/cmp_util.c +++ b/crypto/cmp/cmp_util.c @@ -69,7 +69,8 @@ static OSSL_CMP_severity parse_level(const char *level) } const char *ossl_cmp_log_parse_metadata(const char *buf, - OSSL_CMP_severity *level, char **func, char **file, int *line) + OSSL_CMP_severity *level, + char **func, char **file, int *line) { const char *p_func = buf; const char *p_file = buf == NULL ? NULL : strchr(buf, ':'); @@ -106,6 +107,40 @@ const char *ossl_cmp_log_parse_metadata(const char *buf, return msg; } +#define UNKNOWN_FUNC "(unknown function)" /* the default for OPENSSL_FUNC */ +/* + * substitute fallback if component/function name is NULL or empty or contains + * just pseudo-information "(unknown function)" due to -pedantic and macros.h + */ +static const char *improve_location_name(const char *func, const char *fallback) +{ + if (!ossl_assert(fallback != NULL)) + return NULL; + return func == NULL || *func == '\0' || strcmp(func, UNKNOWN_FUNC) == 0 + ? fallback : func; +} + +int OSSL_CMP_print_to_bio(BIO* bio, const char *component, const char *file, + int line, OSSL_CMP_severity level, const char *msg) +{ + const char *level_string = + level == OSSL_CMP_LOG_EMERG ? "EMERG" : + level == OSSL_CMP_LOG_ALERT ? "ALERT" : + level == OSSL_CMP_LOG_CRIT ? "CRIT" : + level == OSSL_CMP_LOG_ERR ? "error" : + level == OSSL_CMP_LOG_WARNING ? "warning" : + level == OSSL_CMP_LOG_NOTICE ? "NOTE" : + level == OSSL_CMP_LOG_INFO ? "info" : + level == OSSL_CMP_LOG_DEBUG ? "DEBUG" : "(unknown level)"; + +#ifndef NDEBUG + if (BIO_printf(bio, "%s:%s:%d:", improve_location_name(component, "CMP"), + file, line) < 0) + return 0; +#endif + return BIO_printf(bio, OSSL_CMP_LOG_PREFIX"%s: %s\n", + level_string, msg) >= 0; +} /* * auxiliary function for incrementally reporting texts via the error queue @@ -204,31 +239,31 @@ void OSSL_CMP_print_errors_cb(OSSL_cmp_log_cb_t log_fn) const char *file = NULL, *func = NULL, *data = NULL; int line, flags; - if (log_fn == NULL) { -#ifndef OPENSSL_NO_STDIO - ERR_print_errors_fp(stderr); -#else - /* CMPerr(0, CMP_R_NO_STDIO) makes no sense during error printing */ -#endif - return; - } - while ((err = ERR_get_error_all(&file, &line, &func, &data, &flags)) != 0) { - char component[128]; - const char *func_ = func != NULL && *func != '\0' ? func : ""; + const char *component = + improve_location_name(func, ERR_lib_error_string(err)); if (!(flags & ERR_TXT_STRING)) data = NULL; -#ifdef OSSL_CMP_PRINT_LIBINFO - BIO_snprintf(component, sizeof(component), "OpenSSL:%s:%s", - ERR_lib_error_string(err), func_); + BIO_snprintf(msg, sizeof(msg), "%s%s%s", ERR_reason_error_string(err), + data == NULL || *data == '\0' ? "" : " : ", + data == NULL ? "" : data); + if (log_fn == NULL) { +#ifndef OPENSSL_NO_STDIO + BIO *bio = BIO_new_fp(stderr, BIO_NOCLOSE); + + if (bio != NULL) { + OSSL_CMP_print_to_bio(bio, component, file, line, + OSSL_CMP_LOG_ERR, msg); + BIO_free(bio); + } #else - BIO_snprintf(component, sizeof(component), "%s",func_); + /* CMPerr(0, CMP_R_NO_STDIO) makes no sense during error printing */ #endif - BIO_snprintf(msg, sizeof(msg), "%s%s%s", ERR_reason_error_string(err), - data == NULL ? "" : " : ", data == NULL ? "" : data); - if (log_fn(component, file, line, OSSL_CMP_LOG_ERR, msg) <= 0) - break; /* abort outputting the error report */ + } else { + if (log_fn(component, file, line, OSSL_CMP_LOG_ERR, msg) <= 0) + break; /* abort outputting the error report */ + } } } @@ -266,7 +301,7 @@ int ossl_cmp_sk_X509_add1_cert(STACK_OF(X509) *sk, X509 *cert, } int ossl_cmp_sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, - int no_self_signed, int no_dups, int prepend) + int no_self_issued, int no_dups, int prepend) /* compiler would allow 'const' for the list of certs, yet they are up-ref'ed */ { int i; @@ -278,7 +313,7 @@ int ossl_cmp_sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, for (i = 0; i < sk_X509_num(certs); i++) { /* certs may be NULL */ X509 *cert = sk_X509_value(certs, i); - if (!no_self_signed || X509_check_issued(cert, cert) != X509_V_OK) { + if (!no_self_issued || X509_check_issued(cert, cert) != X509_V_OK) { if (!ossl_cmp_sk_X509_add1_cert(sk, cert, no_dups, prepend)) return 0; } @@ -287,7 +322,7 @@ int ossl_cmp_sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, } int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, - int only_self_signed) + int only_self_issued) { int i; @@ -300,7 +335,7 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, for (i = 0; i < sk_X509_num(certs); i++) { X509 *cert = sk_X509_value(certs, i); - if (!only_self_signed || X509_check_issued(cert, cert) == X509_V_OK) + if (!only_self_issued || X509_check_issued(cert, cert) == X509_V_OK) if (!X509_STORE_add_cert(store, cert)) /* ups cert ref counter */ return 0; } @@ -390,10 +425,10 @@ STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert) chain = X509_STORE_CTX_get0_chain(csc); - /* result list to store the up_ref'ed not self-signed certificates */ + /* result list to store the up_ref'ed not self-issued certificates */ if ((result = sk_X509_new_null()) == NULL) goto err; - if (!ossl_cmp_sk_X509_add1_certs(result, chain, 1 /* no self-signed */, + if (!ossl_cmp_sk_X509_add1_certs(result, chain, 1 /* no self-issued */, 1 /* no duplicates */, 0)) { sk_X509_free(result); result = NULL; @@ -438,7 +473,7 @@ int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, return 0; } if (bytes != NULL) { - if ((new = ASN1_OCTET_STRING_new()) == NULL + if ((new = ASN1_OCTET_STRING_new()) == NULL || !(ASN1_OCTET_STRING_set(new, bytes, len))) { ASN1_OCTET_STRING_free(new); return 0; diff --git a/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod b/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod index 08941362fb..a239ca044a 100644 --- a/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod +++ b/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod @@ -2,10 +2,6 @@ =head1 NAME -ossl_cmp_log_parse_metadata, -ossl_cmp_add_error_txt, -ossl_cmp_add_error_data, -ossl_cmp_add_error_line, ossl_cmp_asn1_octet_string_set1, ossl_cmp_asn1_octet_string_set1_bytes, ossl_cmp_build_cert_chain @@ -15,14 +11,6 @@ ossl_cmp_build_cert_chain #include "cmp_local.h" - const char *ossl_cmp_log_parse_metadata(const char *buf, - OSSL_CMP_severity *level, char **func, - char **file, int *line); - - void ossl_cmp_add_error_txt(const char *separator, const char *txt); - #define ossl_cmp_add_error_data(txt) - #define ossl_cmp_add_error_line(txt) - int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt, const ASN1_OCTET_STRING *src); int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, @@ -32,27 +20,6 @@ ossl_cmp_build_cert_chain =head1 DESCRIPTION -ossl_cmp_log_parse_metadata() parses the given message buffer I populated -by L etc. -according to the pattern OSSL_CMP_LOG_START#level ": %s\n", filling in -the variable pointed to by I with the severity level or -1, -the variable pointed to by I with the function name string or NULL, -the variable pointed to by I with the filename string or NULL, and -the variable pointed to by I with the line number or -1. -Any string returned via I<*func> and I<*file> must be freeed by the caller. - -ossl_cmp_add_error_txt() appends text to the extra data field of the last -error message in the OpenSSL error queue, after adding the optional separator -unless data has been empty so far. The text can be of arbitrary length, -which is not possible when using L in conjunction with -L. - -ossl_cmp_add_error_data() is a macro calling -ossl_cmp_add_error_txt() with the separator being ":". - -ossl_cmp_add_error_line() is a macro calling -ossl_cmp_add_error_txt() with the separator being "\n". - ossl_cmp_asn1_octet_string_set1() frees any previous value of the variable referenced via the I argument and assigns either a copy of the ASN1_OCTET_STRING given as the I argument or NULL. @@ -68,15 +35,6 @@ certificates and optionally the (possible) trust anchor(s). =head1 RETURN VALUES -ossl_cmp_log_parse_metadata() returns the pointer to the actual message text -after the OSSL_CMP_LOG_PREFIX and level and ':' if found in the buffer, -else the beginning of the buffer. - -ossl_cmp_add_error_txt() -ossl_cmp_add_error_data(), and -ossl_cmp_add_error_line() -do not return anything. - ossl_cmp_build_cert_chain() returns NULL on error, else a pointer to a stack of (up_ref'ed) certificates containing the EE certificate given in the function arguments (cert) diff --git a/doc/internal/man3/ossl_cmp_print_log.pod b/doc/internal/man3/ossl_cmp_print_log.pod new file mode 100644 index 0000000000..a45897a067 --- /dev/null +++ b/doc/internal/man3/ossl_cmp_print_log.pod @@ -0,0 +1,113 @@ +=pod + +=head1 NAME + +ossl_cmp_print_log, +ossl_cmp_alert, +ossl_cmp_err, +ossl_cmp_warn, +ossl_cmp_info, +ossl_cmp_debug, +ossl_cmp_log, +ossl_cmp_log1, +ossl_cmp_log2, +ossl_cmp_log3, +ossl_cmp_log4, +ossl_cmp_log_parse_metadata, +ossl_cmp_add_error_txt, +ossl_cmp_add_error_data, +ossl_cmp_add_error_line +- logging and error reporting support for CMP + +=head1 SYNOPSIS + + #include "cmp_local.h" + + int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, + const char *func, const char *file, int line, + const char *level_str, const char *format, ...); + #define ossl_cmp_alert(ctx, msg) + #define ossl_cmp_err(ctx, msg) + #define ossl_cmp_warn(ctx, msg) + #define ossl_cmp_info(ctx, msg) + #define ossl_cmp_debug(ctx, (msg) + #define ossl_cmp_log(level, ctx, msg) + #define ossl_cmp_log1(level, ctx, fmt, arg1) + #define ossl_cmp_log2(level, ctx, fmt, arg1, arg2) + #define ossl_cmp_log3(level, ctx, fmt, arg1, arg2, arg3) + #define ossl_cmp_log4(level, ctx, fmt, arg1, arg2, arg3, arg4) + const char *ossl_cmp_log_parse_metadata(const char *buf, + OSSL_CMP_severity *level, char **func, + char **file, int *line); + + void ossl_cmp_add_error_txt(const char *separator, const char *txt); + #define ossl_cmp_add_error_data(txt) + #define ossl_cmp_add_error_line(txt) + +=head1 DESCRIPTION + +ossl_cmp_print_log() prints CMP log messages (i.e., diagnostic info) via the +log callback of the B if present and the severity level is sufficient. +If the trace API if enabled the function uses it, prepending the function name, +filename, line number, and severity information to the message being output. +In any case the B, B, B, and B parameters +and the message constructed using the given B and variable further +argument list are passed to the log callback function (unless it is NULL). +The B, B, B, and B arguments may be NULL. + +ossl_cmp_alert(), ossl_cmp_err(), ossl_cmp_warn(), ossl_cmp_info(), and +ossl_cmp_debug() output a simple alert/error/warning/info/debug message +via ossl_cmp_print_log(). + +ossl_cmp_log(), ossl_cmp_log1(), ossl_cmp_log2(), ossl_cmp_log3(), and +ossl_cmp_log4() output a log message with the given severity, +constructing the message text from the given format and arguments. + +ossl_cmp_log_parse_metadata() parses the given message buffer I populated +by ossl_cmp_log() etc. +according to the pattern OSSL_CMP_LOG_START#level ": %s\n", filling in +the variable pointed to by I with the severity level or -1, +the variable pointed to by I with the function name string or NULL, +the variable pointed to by I with the filename string or NULL, and +the variable pointed to by I with the line number or -1. +Any string returned via I<*func> and I<*file> must be freeed by the caller. + +ossl_cmp_add_error_txt() appends text to the extra data field of the last +error message in the OpenSSL error queue, after adding the optional separator +unless data has been empty so far. The text can be of arbitrary length, +which is not possible when using L in conjunction with +L. + +ossl_cmp_add_error_data() is a macro calling +ossl_cmp_add_error_txt() with the separator being ":". + +ossl_cmp_add_error_line() is a macro calling +ossl_cmp_add_error_txt() with the separator being "\n". + +=head1 RETURN VALUES + +ossl_cmp_log_parse_metadata() returns the pointer to the actual message text +after the OSSL_CMP_LOG_PREFIX and level and ':' if found in the buffer, +else the beginning of the buffer. + +ossl_cmp_add_error_txt() +ossl_cmp_add_error_data(), and +ossl_cmp_add_error_line() +do not return anything. + +All other functions return 1 on success, 0 on error. + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/OSSL_CMP_log_open.pod b/doc/man3/OSSL_CMP_log_open.pod index 64399e2b72..9f204d6ec1 100644 --- a/doc/man3/OSSL_CMP_log_open.pod +++ b/doc/man3/OSSL_CMP_log_open.pod @@ -4,16 +4,6 @@ OSSL_CMP_log_open, OSSL_CMP_log_close, -OSSL_CMP_alert, -OSSL_CMP_err, -OSSL_CMP_warn, -OSSL_CMP_info, -OSSL_CMP_debug, -OSSL_CMP_log, -OSSL_CMP_log1, -OSSL_CMP_log2, -OSSL_CMP_log3, -OSSL_CMP_log4, OSSL_CMP_severity, OSSL_CMP_LOG_EMERG, OSSL_CMP_LOG_ALERT, @@ -24,6 +14,7 @@ OSSL_CMP_LOG_NOTICE, OSSL_CMP_LOG_INFO, OSSL_CMP_LOG_DEBUG, OSSL_cmp_log_cb_t, +OSSL_CMP_print_to_bio, OSSL_CMP_print_errors_cb - functions for logging and error reporting @@ -33,16 +24,6 @@ OSSL_CMP_print_errors_cb int OSSL_CMP_log_open(void); void OSSL_CMP_log_close(void); - #define OSSL_CMP_alert(msg) - #define OSSL_CMP_err(msg) - #define OSSL_CMP_warn(msg) - #define OSSL_CMP_info(msg) - #define OSSL_CMP_debug(msg) - #define OSSL_CMP_log(level, msg) - #define OSSL_CMP_log1(level, fmt, arg1) - #define OSSL_CMP_log2(level, fmt, arg1, arg2) - #define OSSL_CMP_log3(level, fmt, arg1, arg2, arg3) - #define OSSL_CMP_log4(level, fmt, arg1, arg2, arg3, arg4) /* severity level declarations resemble those from syslog.h */ typedef int OSSL_CMP_severity; @@ -54,16 +35,18 @@ OSSL_CMP_print_errors_cb #define OSSL_CMP_LOG_NOTICE 5 #define OSSL_CMP_LOG_INFO 6 #define OSSL_CMP_LOG_DEBUG 7 + typedef int (*OSSL_cmp_log_cb_t)(const char *component, const char *file, int line, OSSL_CMP_severity level, const char *msg); - + int OSSL_CMP_print_to_bio(BIO *bio, const char *component, const char *file, + int line, OSSL_CMP_severity level, const char *msg); void OSSL_CMP_print_errors_cb(OSSL_cmp_log_cb_t log_fn); =head1 DESCRIPTION The logging and error reporting facility described here contains -convenience functions for CMP-specific logging via the trace API, +convenience functions for CMP-specific logging, including a string prefix mirroring the severity levels of syslog.h, and enhancements of the error queue mechanism needed for large diagnostic messages produced by the CMP library in case of certificate validation failures. @@ -73,12 +56,12 @@ should be provided for user information, debugging, and auditing purposes. A CMP application can obtain this information by providing a callback function with the following type: - typedef void (*OSSL_cmp_log_cb_t)(const char *component, - const char *file, int line, - OSSL_CMP_severity level, const char *msg); + typedef int (*OSSL_cmp_log_cb_t)(const char *component, + const char *file, int line, + OSSL_CMP_severity level, const char *msg); The parameters may provide -a component identifier (which may be a library name or function name) or NULL, +some component info (which may be a module name and/or function name) or NULL, a file pathname or NULL, a line number or 0 indicating the source code location, a severity level, and @@ -105,19 +88,15 @@ OSSL_CMP_log_close() may be called when all activities are finished to flush any pending CMP-specific log output and deallocate related resources. It may be called multiple times. It does get called at OpenSSL stutdown. -OSSL_CMP_alert() outputs a simple alert message via the trace API. -OSSL_CMP_err() outputs a simple error message via the trace API. -OSSL_CMP_warn() outputs a simple warning message via the trace API. -OSSL_CMP_info() outputs a simple info message via the trace API. -OSSL_CMP_debug() outputs a simple debug message via the trace API. - -Note that due to the design of the trace API used, the log functions have no -effect unless the B option is used during build configuration. +OSSL_CMP_print_to_bio() prints the given component info, filename, line number, +severity level, and log message or error queue message to the given B. +B usually is a function or module name. +If it is NULL, empty, or "(unknown function)" then "CMP" is used as fallback. OSSL_CMP_print_errors_cb() outputs any entries in the OpenSSL error queue. It is similar to B but uses the CMP log callback function -C for uniformity with CMP logging if not B. Otherwise it uses -B to print to STDERR (unless OPENSSL_NO_STDIO is defined). +C for uniformity with CMP logging if not B. Otherwise it prints to +STDERR using B (unless OPENSSL_NO_STDIO is defined). =head1 RETURN VALUES diff --git a/include/openssl/cmp_util.h b/include/openssl/cmp_util.h index ee368afa60..69e843c64e 100644 --- a/include/openssl/cmp_util.h +++ b/include/openssl/cmp_util.h @@ -19,39 +19,13 @@ # include # include -# ifdef __cplusplus +# ifdef __cplusplus extern "C" { # endif -/* - * convenience functions for CMP-specific logging via the trace API - */ int OSSL_CMP_log_open(void); void OSSL_CMP_log_close(void); # define OSSL_CMP_LOG_PREFIX "CMP " -/* in OSSL_CMP_LOG_START, cannot use OPENSSL_FUNC when expands to __func__ */ -# define OSSL_CMP_LOG_START "%s:" OPENSSL_FILE ":" \ - OPENSSL_MSTR(OPENSSL_LINE) ":" OSSL_CMP_LOG_PREFIX -# define OSSL_CMP_alert(msg) OSSL_CMP_log(ALERT, msg) -# define OSSL_CMP_err(msg) OSSL_CMP_log(ERROR, msg) -# define OSSL_CMP_warn(msg) OSSL_CMP_log(WARN, msg) -# define OSSL_CMP_info(msg) OSSL_CMP_log(INFO, msg) -# define OSSL_CMP_debug(msg) OSSL_CMP_log(DEBUG, msg) -# define OSSL_CMP_log(level, msg) \ - OSSL_TRACEV(CMP, (trc_out, OSSL_CMP_LOG_START#level ": %s\n", \ - OPENSSL_FUNC, msg)) -# define OSSL_CMP_log1(level, fmt, arg1) \ - OSSL_TRACEV(CMP, (trc_out, OSSL_CMP_LOG_START#level ": " fmt "\n", \ - OPENSSL_FUNC, arg1)) -# define OSSL_CMP_log2(level, fmt, arg1, arg2) \ - OSSL_TRACEV(CMP, (trc_out, OSSL_CMP_LOG_START#level ": " fmt "\n", \ - OPENSSL_FUNC, arg1, arg2)) -# define OSSL_CMP_log3(level, fmt, arg1, arg2, arg3) \ - OSSL_TRACEV(CMP, (trc_out, OSSL_CMP_LOG_START#level ": " fmt "\n", \ - OPENSSL_FUNC, arg1, arg2, arg3)) -# define OSSL_CMP_log4(level, fmt, arg1, arg2, arg3, arg4) \ - OSSL_TRACEV(CMP, (trc_out, OSSL_CMP_LOG_START#level ": " fmt "\n", \ - OPENSSL_FUNC, arg1, arg2, arg3, arg4)) /* * generalized logging/error callback mirroring the severity levels of syslog.h @@ -68,6 +42,8 @@ typedef int OSSL_CMP_severity; typedef int (*OSSL_cmp_log_cb_t)(const char *func, const char *file, int line, OSSL_CMP_severity level, const char *msg); +int OSSL_CMP_print_to_bio(BIO* bio, const char *component, const char *file, + int line, OSSL_CMP_severity level, const char *msg); /* use of the logging callback for outputting error queue */ void OSSL_CMP_print_errors_cb(OSSL_cmp_log_cb_t log_fn); diff --git a/test/cmp_ctx_test.c b/test/cmp_ctx_test.c index c007cfb35e..e6b6f24854 100644 --- a/test/cmp_ctx_test.c +++ b/test/cmp_ctx_test.c @@ -195,7 +195,7 @@ static int execute_CTX_reqExtensions_have_SAN_test( { OSSL_CMP_CTX *ctx = fixture->ctx; const int len = 16; - unsigned char str[16 /* = len */ ]; + unsigned char str[16 /* = len */]; ASN1_OCTET_STRING *data = NULL; X509_EXTENSION *ext = NULL; X509_EXTENSIONS *exts = NULL; @@ -234,7 +234,6 @@ static int test_CTX_reqExtensions_have_SAN(void) return result; } -#ifndef OPENSSL_NO_TRACE static int test_log_line; static int test_log_cb_res = 0; static int test_log_cb(const char *func, const char *file, int line, @@ -242,21 +241,20 @@ static int test_log_cb(const char *func, const char *file, int line, { test_log_cb_res = # ifndef PEDANTIC - (strcmp(func, "execute_cmp_ctx_log_cb_test") == 0 - || strcmp(func, "(unknown function)") == 0) && + (TEST_str_eq(func, "execute_cmp_ctx_log_cb_test") + || TEST_str_eq(func, "(unknown function)")) && # endif - (strcmp(file, OPENSSL_FILE) == 0 || strcmp(file, "(no file)") == 0) - && (line == test_log_line || line == 0) - && (level == OSSL_CMP_LOG_INFO || level == -1) - && strcmp(msg, "ok\n") == 0; + (TEST_str_eq(file, OPENSSL_FILE) + || TEST_str_eq(file, "(no file)")) + && (TEST_int_eq(line, test_log_line) || TEST_int_eq(line, 0)) + && (TEST_int_eq(level, OSSL_CMP_LOG_INFO) || TEST_int_eq(level, -1)) + && TEST_str_eq(msg, "ok"); return 1; } -#endif static int execute_cmp_ctx_log_cb_test(OSSL_CMP_CTX_TEST_FIXTURE *fixture) { int res = 1; -#if !defined OPENSSL_NO_TRACE && !defined OPENSSL_NO_STDIO OSSL_CMP_CTX *ctx = fixture->ctx; OSSL_TRACE(ALL, "this general trace message is not shown by default\n"); @@ -267,30 +265,29 @@ static int execute_cmp_ctx_log_cb_test(OSSL_CMP_CTX_TEST_FIXTURE *fixture) if (!TEST_true(OSSL_CMP_CTX_set_log_cb(ctx, NULL))) { res = 0; } else { - OSSL_CMP_err("this should be printed as CMP error message"); - OSSL_CMP_warn("this should be printed as CMP warning message"); - OSSL_CMP_debug("this should not be printed"); + ossl_cmp_err(ctx, "this should be printed as CMP error message"); + ossl_cmp_warn(ctx, "this should be printed as CMP warning message"); + ossl_cmp_debug(ctx, "this should not be printed"); TEST_true(OSSL_CMP_CTX_set_log_verbosity(ctx, OSSL_CMP_LOG_DEBUG)); - OSSL_CMP_debug("this should be printed as CMP debug message"); + ossl_cmp_debug(ctx, "this should be printed as CMP debug message"); TEST_true(OSSL_CMP_CTX_set_log_verbosity(ctx, OSSL_CMP_LOG_INFO)); } if (!TEST_true(OSSL_CMP_CTX_set_log_cb(ctx, test_log_cb))) { res = 0; } else { test_log_line = OPENSSL_LINE + 1; - OSSL_CMP_log2(INFO, "%s%c", "o", 'k'); + ossl_cmp_log2(INFO, ctx, "%s%c", "o", 'k'); if (!TEST_int_eq(test_log_cb_res, 1)) res = 0; OSSL_CMP_CTX_set_log_verbosity(ctx, OSSL_CMP_LOG_ERR); test_log_cb_res = -1; /* callback should not be called at all */ test_log_line = OPENSSL_LINE + 1; - OSSL_CMP_log2(INFO, "%s%c", "o", 'k'); + ossl_cmp_log2(INFO, ctx, "%s%c", "o", 'k'); if (!TEST_int_eq(test_log_cb_res, -1)) res = 0; } OSSL_CMP_log_close(); OSSL_CMP_log_close(); /* multiple calls should be harmless */ -#endif return res; } @@ -715,9 +712,7 @@ DEFINE_SET_GET_ARG_FN(set, get, option, 16, int) DEFINE_SET_GET_BASE_TEST(OSSL_CMP_CTX, set, get, 0, option_16, int, -1, IS_0, \ 1 /* true */, DROP) -#ifndef OPENSSL_NO_TRACE DEFINE_SET_CB_TEST(log_cb) -#endif DEFINE_SET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, serverPath, char, IS_0) DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, serverName, char) @@ -788,13 +783,11 @@ int setup_tests(void) /* various CMP options: */ ADD_TEST(test_CTX_set_get_option_16); /* CMP-specific callback for logging and outputting the error queue: */ -#ifndef OPENSSL_NO_TRACE ADD_TEST(test_CTX_set_get_log_cb); -#endif /* * also tests OSSL_CMP_log_open(), OSSL_CMP_CTX_set_log_verbosity(), - * OSSL_CMP_err(), OSSL_CMP_warn(), * OSSL_CMP_debug(), - * OSSL_CMP_log2(), ossl_cmp_log_parse_metadata(), and OSSL_CMP_log_close() + * ossl_cmp_err(), ossl_cmp_warn(), * ossl_cmp_debug(), + * ossl_cmp_log2(), ossl_cmp_log_parse_metadata(), and OSSL_CMP_log_close() * with OSSL_CMP_severity OSSL_CMP_LOG_ERR/WARNING/DEBUG/INFO: */ ADD_TEST(test_cmp_ctx_log_cb); diff --git a/util/other.syms b/util/other.syms index 378dda3659..27e9a92374 100644 --- a/util/other.syms +++ b/util/other.syms @@ -359,17 +359,7 @@ OSSL_CMP_LOG_NOTICE define OSSL_CMP_LOG_WARNING define OSSL_CMP_MSTR_HELPER define OSSL_CMP_MSTR define -OSSL_CMP_alert define -OSSL_CMP_debug define -OSSL_CMP_err define -OSSL_CMP_info define -OSSL_CMP_log define -OSSL_CMP_log1 define -OSSL_CMP_log2 define -OSSL_CMP_log3 define -OSSL_CMP_log4 define OSSL_CMP_severity datatype -OSSL_CMP_warn define OSSL_cmp_certConf_cb_t datatype OSSL_cmp_log_cb_t datatype OSSL_cmp_transfer_cb_t datatype