From 197896ba1b3b2d4880661513de725b364c0dbfbd Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 18 Jun 2020 22:18:59 +0300 Subject: [PATCH] tls/openssl: improve logging Log error names and codes to increase verbosity in debug mode. --- src/tls_openssl.c | 118 ++++++++++++++++++++++++++++++++++++++++++++-- src/util.h | 4 ++ 2 files changed, 118 insertions(+), 4 deletions(-) diff --git a/src/tls_openssl.c b/src/tls_openssl.c index b92d10f..34398af 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -62,10 +62,109 @@ enum { }; static void _tls_sock_wait(tls_t *tls, int error); +static const char *_tls_error_str(int error, const char **tbl, size_t tbl_size); static void _tls_set_error(tls_t *tls, int error); static void _tls_log_error(xmpp_ctx_t *ctx); static void _tls_dump_cert_info(tls_t *tls); +#define TLS_ERROR_STR(error, table) \ + _tls_error_str(error, table, ARRAY_SIZE(table)) + +#define TLS_ERROR_FIELD(x) [x] = #x +const char *tls_errors[] = { + TLS_ERROR_FIELD(SSL_ERROR_NONE), + TLS_ERROR_FIELD(SSL_ERROR_SSL), + TLS_ERROR_FIELD(SSL_ERROR_WANT_READ), + TLS_ERROR_FIELD(SSL_ERROR_WANT_WRITE), + TLS_ERROR_FIELD(SSL_ERROR_WANT_X509_LOOKUP), + TLS_ERROR_FIELD(SSL_ERROR_SYSCALL), + TLS_ERROR_FIELD(SSL_ERROR_ZERO_RETURN), + TLS_ERROR_FIELD(SSL_ERROR_WANT_CONNECT), + TLS_ERROR_FIELD(SSL_ERROR_WANT_ACCEPT), + TLS_ERROR_FIELD(SSL_ERROR_WANT_ASYNC), + TLS_ERROR_FIELD(SSL_ERROR_WANT_ASYNC_JOB), + TLS_ERROR_FIELD(SSL_ERROR_WANT_CLIENT_HELLO_CB), +}; +const char *cert_errors[] = { + TLS_ERROR_FIELD(X509_V_OK), + TLS_ERROR_FIELD(X509_V_ERR_UNSPECIFIED), + TLS_ERROR_FIELD(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT), + TLS_ERROR_FIELD(X509_V_ERR_UNABLE_TO_GET_CRL), + TLS_ERROR_FIELD(X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE), + TLS_ERROR_FIELD(X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE), + TLS_ERROR_FIELD(X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY), + TLS_ERROR_FIELD(X509_V_ERR_CERT_SIGNATURE_FAILURE), + TLS_ERROR_FIELD(X509_V_ERR_CRL_SIGNATURE_FAILURE), + TLS_ERROR_FIELD(X509_V_ERR_CERT_NOT_YET_VALID), + TLS_ERROR_FIELD(X509_V_ERR_CERT_HAS_EXPIRED), + TLS_ERROR_FIELD(X509_V_ERR_CRL_NOT_YET_VALID), + TLS_ERROR_FIELD(X509_V_ERR_CRL_HAS_EXPIRED), + TLS_ERROR_FIELD(X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD), + TLS_ERROR_FIELD(X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD), + TLS_ERROR_FIELD(X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD), + TLS_ERROR_FIELD(X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD), + TLS_ERROR_FIELD(X509_V_ERR_OUT_OF_MEM), + TLS_ERROR_FIELD(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT), + TLS_ERROR_FIELD(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN), + TLS_ERROR_FIELD(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY), + TLS_ERROR_FIELD(X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE), + TLS_ERROR_FIELD(X509_V_ERR_CERT_CHAIN_TOO_LONG), + TLS_ERROR_FIELD(X509_V_ERR_CERT_REVOKED), + TLS_ERROR_FIELD(X509_V_ERR_INVALID_CA), + TLS_ERROR_FIELD(X509_V_ERR_PATH_LENGTH_EXCEEDED), + TLS_ERROR_FIELD(X509_V_ERR_INVALID_PURPOSE), + TLS_ERROR_FIELD(X509_V_ERR_CERT_UNTRUSTED), + TLS_ERROR_FIELD(X509_V_ERR_CERT_REJECTED), + TLS_ERROR_FIELD(X509_V_ERR_SUBJECT_ISSUER_MISMATCH), + TLS_ERROR_FIELD(X509_V_ERR_AKID_SKID_MISMATCH), + TLS_ERROR_FIELD(X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH), + TLS_ERROR_FIELD(X509_V_ERR_KEYUSAGE_NO_CERTSIGN), + TLS_ERROR_FIELD(X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER), + TLS_ERROR_FIELD(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION), + TLS_ERROR_FIELD(X509_V_ERR_KEYUSAGE_NO_CRL_SIGN), + TLS_ERROR_FIELD(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION), + TLS_ERROR_FIELD(X509_V_ERR_INVALID_NON_CA), + TLS_ERROR_FIELD(X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED), + TLS_ERROR_FIELD(X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE), + TLS_ERROR_FIELD(X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED), + TLS_ERROR_FIELD(X509_V_ERR_INVALID_EXTENSION), + TLS_ERROR_FIELD(X509_V_ERR_INVALID_POLICY_EXTENSION), + TLS_ERROR_FIELD(X509_V_ERR_NO_EXPLICIT_POLICY), + TLS_ERROR_FIELD(X509_V_ERR_DIFFERENT_CRL_SCOPE), + TLS_ERROR_FIELD(X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE), + TLS_ERROR_FIELD(X509_V_ERR_UNNESTED_RESOURCE), + TLS_ERROR_FIELD(X509_V_ERR_PERMITTED_VIOLATION), + TLS_ERROR_FIELD(X509_V_ERR_EXCLUDED_VIOLATION), + TLS_ERROR_FIELD(X509_V_ERR_SUBTREE_MINMAX), + TLS_ERROR_FIELD(X509_V_ERR_APPLICATION_VERIFICATION), + TLS_ERROR_FIELD(X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE), + TLS_ERROR_FIELD(X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX), + TLS_ERROR_FIELD(X509_V_ERR_UNSUPPORTED_NAME_SYNTAX), + TLS_ERROR_FIELD(X509_V_ERR_CRL_PATH_VALIDATION_ERROR), + TLS_ERROR_FIELD(X509_V_ERR_PATH_LOOP), + TLS_ERROR_FIELD(X509_V_ERR_SUITE_B_INVALID_VERSION), + TLS_ERROR_FIELD(X509_V_ERR_SUITE_B_INVALID_ALGORITHM), + TLS_ERROR_FIELD(X509_V_ERR_SUITE_B_INVALID_CURVE), + TLS_ERROR_FIELD(X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM), + TLS_ERROR_FIELD(X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED), + TLS_ERROR_FIELD(X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256), + TLS_ERROR_FIELD(X509_V_ERR_HOSTNAME_MISMATCH), + TLS_ERROR_FIELD(X509_V_ERR_EMAIL_MISMATCH), + TLS_ERROR_FIELD(X509_V_ERR_IP_ADDRESS_MISMATCH), + TLS_ERROR_FIELD(X509_V_ERR_DANE_NO_MATCH), + TLS_ERROR_FIELD(X509_V_ERR_EE_KEY_TOO_SMALL), + TLS_ERROR_FIELD(X509_V_ERR_CA_KEY_TOO_SMALL), + TLS_ERROR_FIELD(X509_V_ERR_CA_MD_TOO_WEAK), + TLS_ERROR_FIELD(X509_V_ERR_INVALID_CALL), + TLS_ERROR_FIELD(X509_V_ERR_STORE_LOOKUP), + TLS_ERROR_FIELD(X509_V_ERR_NO_VALID_SCTS), + TLS_ERROR_FIELD(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION), + TLS_ERROR_FIELD(X509_V_ERR_OCSP_VERIFY_NEEDED), + TLS_ERROR_FIELD(X509_V_ERR_OCSP_VERIFY_FAILED), + TLS_ERROR_FIELD(X509_V_ERR_OCSP_CERT_UNKNOWN), +}; +#undef TLS_ERROR_FIELD + void tls_initialize(void) { #if OPENSSL_VERSION_NUMBER < 0x10100000L @@ -160,7 +259,7 @@ tls_t *tls_new(xmpp_conn_t *conn) /* Trust server's certificate when user sets the flag explicitly. */ mode = conn->tls_trust ? SSL_VERIFY_NONE : SSL_VERIFY_PEER; - SSL_set_verify(tls->ssl, mode, 0); + SSL_set_verify(tls->ssl, mode, NULL); #if OPENSSL_VERSION_NUMBER >= 0x10002000L /* Hostname verification is supported in OpenSSL 1.0.2 and newer. */ param = SSL_get0_param(tls->ssl); @@ -231,8 +330,13 @@ int tls_start(tls_t *tls) } x509_res = SSL_get_verify_result(tls->ssl); - xmpp_debug(tls->ctx, "tls", "Certificate verification %s", - x509_res == X509_V_OK ? "passed" : "FAILED"); + if (x509_res == X509_V_OK) { + xmpp_debug(tls->ctx, "tls", "Certificate verification passed"); + } else { + xmpp_debug(tls->ctx, "tls", + "Certificate verification FAILED, result=%s(%ld)", + TLS_ERROR_STR((int)x509_res, cert_errors), x509_res); + } _tls_dump_cert_info(tls); _tls_set_error(tls, error); @@ -338,10 +442,16 @@ static void _tls_sock_wait(tls_t *tls, int error) } while (ret == -1 && errno == EINTR); } +static const char *_tls_error_str(int error, const char **tbl, size_t tbl_size) +{ + return (error >= 0 && (size_t)error < tbl_size) ? tbl[error] : "UNKNOWN"; +} + static void _tls_set_error(tls_t *tls, int error) { if (error != 0 && !tls_is_recoverable(error)) { - xmpp_debug(tls->ctx, "tls", "error=%d errno=%d", error, errno); + xmpp_debug(tls->ctx, "tls", "error=%s(%d) errno=%d", + TLS_ERROR_STR(error, tls_errors), error, errno); _tls_log_error(tls->ctx); } tls->lasterror = error; diff --git a/src/util.h b/src/util.h index 2b2d9e0..36a5954 100644 --- a/src/util.h +++ b/src/util.h @@ -18,6 +18,10 @@ #include "ostypes.h" +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif /* ARRAY_SIZE */ + /* TODO evaluate x and y only once */ #define xmpp_min(x, y) ((x) < (y) ? (x) : (y))