@cryptotaxi247 / netdata-1 / commits / 8a15f8fbf

Improve certificate verification error logging in ACLK connections (#21513)

* Improve certificate verification error logging and memory handling in ACLK clients Replace deprecated `X509_NAME_oneline` with `BIO` for more robust subject name extraction. Ensure proper management of `BIO` resources to prevent memory leaks. Provide fallback logging for cases where subject name extraction fails. * Additional checks for certificate verification * Resolve windows compilation conflict * Improve netdata_ssl_log_verify_error

Stelios Fragkakis committed Jan 5, 2026 at 10:23 UTC 8a15f8fbf004f812f4b90453b35476eacb6cac90
5 files changed +60 -21
src/aclk/https_client.c
+2 -11
@@ -737,20 +737,11 @@ err_exit:
737
738 static int cert_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
739 {
740 - X509 *err_cert;
741 - int err, depth;
742 - char *err_str;
740 + int err = 0;
741
742 if (!preverify_ok) {
743 err = X509_STORE_CTX_get_error(ctx);
746 - depth = X509_STORE_CTX_get_error_depth(ctx);
747 - err_cert = X509_STORE_CTX_get_current_cert(ctx);
748 - err_str = X509_NAME_oneline(X509_get_subject_name(err_cert), NULL, 0);
749 -
750 - netdata_log_error("Cert Chain verify error:num=%d:%s:depth=%d:%s", err,
751 - X509_verify_cert_error_string(err), depth, err_str);
752 -
753 - free(err_str);
744 + netdata_ssl_log_verify_error(ctx);
745 }
746
747 if(cloud_config_insecure_get()) {
src/aclk/mqtt_websockets/mqtt_wss_client.c
+1 -10
@@ -239,18 +239,9 @@ static int cert_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
239 SSL* ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
240 mqtt_wss_client client = SSL_get_ex_data(ssl, 0);
241
242 - // TODO handle depth as per https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_verify.html
243 -
242 if (!preverify_ok) {
243 err = X509_STORE_CTX_get_error(ctx);
246 - int depth = X509_STORE_CTX_get_error_depth(ctx);
247 - X509* err_cert = X509_STORE_CTX_get_current_cert(ctx);
248 - char* err_str = X509_NAME_oneline(X509_get_subject_name(err_cert), NULL, 0);
249 -
250 - nd_log(NDLS_DAEMON, NDLP_ERR, "verify error:num=%d:%s:depth=%d:%s", err,
251 - X509_verify_cert_error_string(err), depth, err_str);
252 -
253 - freez(err_str);
244 + netdata_ssl_log_verify_error(ctx);
245 }
246
247 if (!preverify_ok && err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
src/libnetdata/common.h
+17
@@ -466,6 +466,23 @@ typedef uint32_t uid_t;
466 #include <wbemidl.h>
467 #include <sddl.h>
468 // #include <winternl.h> // conflicts on STRING,
469 +
470 +// wincrypt.h (included via windows.h) defines macros that conflict with OpenSSL
471 +#ifdef X509_NAME
472 +#undef X509_NAME
473 +#endif
474 +#ifdef X509_EXTENSIONS
475 +#undef X509_EXTENSIONS
476 +#endif
477 +#ifdef PKCS7_SIGNER_INFO
478 +#undef PKCS7_SIGNER_INFO
479 +#endif
480 +#ifdef OCSP_REQUEST
481 +#undef OCSP_REQUEST
482 +#endif
483 +#ifdef OCSP_RESPONSE
484 +#undef OCSP_RESPONSE
485 +#endif
486 #endif
487
488 // --------------------------------------------------------------------------------------------------------------------
src/libnetdata/socket/security.c
+38
@@ -858,3 +858,41 @@ int ssl_security_location_for_context(SSL_CTX *ctx, const char *file, const char
858
859 return 0;
860 }
861 +
862 +void netdata_ssl_log_verify_error(X509_STORE_CTX *ctx) {
863 + int err = X509_STORE_CTX_get_error(ctx);
864 + int depth = X509_STORE_CTX_get_error_depth(ctx);
865 +
866 + BIO *bio = NULL;
867 + const char *subject = NULL;
868 + int subject_len = 0;
869 +
870 + X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
871 + if (cert) {
872 + X509_NAME *name = X509_get_subject_name(cert);
873 + if (name) {
874 + bio = BIO_new(BIO_s_mem());
875 + if (bio && X509_NAME_print_ex(bio, name, 0, XN_FLAG_ONELINE) >= 0) {
876 + BUF_MEM *bptr = NULL;
877 + /* Optional defensive check:
878 + * BIO_get_mem_ptr() returns 1 on success, 0 on failure. */
879 + if (BIO_get_mem_ptr(bio, &bptr) > 0 && bptr && bptr->data && bptr->length > 0) {
880 + subject = bptr->data;
881 + subject_len = (int)bptr->length;
882 + }
883 + }
884 + }
885 + }
886 +
887 + if (subject && subject_len > 0) {
888 + nd_log(NDLS_DAEMON, NDLP_ERR,
889 + "SSL: certificate verify error %d:%s at depth %d, subject: %.*s",
890 + err, X509_verify_cert_error_string(err), depth, subject_len, subject);
891 + } else {
892 + nd_log(NDLS_DAEMON, NDLP_ERR,
893 + "SSL: certificate verify error %d:%s at depth %d",
894 + err, X509_verify_cert_error_string(err), depth);
895 + }
896 +
897 + BIO_free(bio);
898 +}
src/libnetdata/socket/security.h
+2
@@ -53,4 +53,6 @@ ssize_t netdata_ssl_peek(NETDATA_SSL *ssl, void *buf, size_t num);
53 ssize_t netdata_ssl_pending(NETDATA_SSL *ssl);
54 bool netdata_ssl_has_pending(NETDATA_SSL *ssl);
55
56 +void netdata_ssl_log_verify_error(X509_STORE_CTX *ctx);
57 +
58 #endif //NETDATA_SECURITY_H