improve CMP logging according to comments on CMP chunk 7 preview
[openssl.git] / crypto / cmp / cmp_ctx.c
index 4bec73c3b797550e0ff3a6f8a35596ceb88752a8..12492336ef63265de7b874cc0f150c36fefb65d7 100644 (file)
@@ -13,7 +13,7 @@
 #include <openssl/bio.h>
 #include <openssl/ocsp.h> /* for OCSP_REVOKED_STATUS_* */
 
-#include "cmp_int.h"
+#include "cmp_local.h"
 
 /* explicit #includes not strictly needed since implied by the above: */
 #include <openssl/cmp.h>
@@ -68,14 +68,21 @@ STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
  */
 int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
 {
+    STACK_OF(X509) *untrusted_certs;
     if (ctx == NULL) {
         CMPerr(0, CMP_R_NULL_ARGUMENT);
         return 0;
     }
-    sk_X509_pop_free(ctx->untrusted_certs, X509_free);
-    if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL)
+    if ((untrusted_certs = sk_X509_new_null()) == NULL)
         return 0;
-    return ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, certs, 0, 1, 0);
+    if (ossl_cmp_sk_X509_add1_certs(untrusted_certs, certs, 0, 1, 0) != 1)
+        goto err;
+    sk_X509_pop_free(ctx->untrusted_certs, X509_free);
+    ctx->untrusted_certs = untrusted_certs;
+    return 1;
+err:
+    sk_X509_pop_free(untrusted_certs, X509_free);
+    return 0;
 }
 
 /*
@@ -195,7 +202,7 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
 int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status)
 {
     if (!ossl_assert(ctx != NULL))
-         return 0;
+        return 0;
     ctx->status = status;
     return 1;
 }
@@ -294,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;
@@ -305,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:
@@ -322,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
@@ -373,13 +431,19 @@ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
 int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec,
                                   const int len)
 {
+    ASN1_OCTET_STRING *secretValue = NULL;
     if (ctx == NULL) {
         CMPerr(0, CMP_R_NULL_ARGUMENT);
         return 0;
     }
-    if (ctx->secretValue != NULL)
+    if (ossl_cmp_asn1_octet_string_set1_bytes(&secretValue, sec, len) != 1)
+        return 0;
+    if (ctx->secretValue != NULL) {
         OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length);
-    return ossl_cmp_asn1_octet_string_set1_bytes(&ctx->secretValue, sec, len);
+        ASN1_OCTET_STRING_free(ctx->secretValue);
+    }
+    ctx->secretValue = secretValue;
+    return 1;
 }
 
 /*
@@ -755,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;
@@ -806,7 +870,7 @@ int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port)
  * sets the http connect/disconnect callback function to be used for HTTP(S)
  * returns 1 on success, 0 on error
  */
-int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_http_cb_t cb)
+int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
 {
     if (ctx == NULL) {
         CMPerr(0, CMP_R_NULL_ARGUMENT);
@@ -933,7 +997,8 @@ int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx)
  * Sets a Boolean or integer option of the context to the "val" arg.
  * Returns 1 on success, 0 on error
  */
-int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) {
+int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
+{
     int min_val;
 
     if (ctx == NULL) {
@@ -1036,7 +1101,8 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) {
  * Reads a Boolean or integer option value from the context.
  * Returns -1 on error (which is the default OSSL_CMP_OPT_REVOCATION_REASON)
  */
-int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) {
+int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
+{
     if (ctx == NULL) {
         CMPerr(0, CMP_R_NULL_ARGUMENT);
         return -1;