tls/openssl: be more verbose

Log non-recoverable errors. The openssl error queue can contain useful
information.
This commit is contained in:
Dmitry Podgorny
2016-04-19 18:21:27 +00:00
parent 4b444ea699
commit ba7422c893

View File

@@ -22,6 +22,7 @@
#endif #endif
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h>
#include "common.h" #include "common.h"
#include "tls.h" #include "tls.h"
@@ -35,6 +36,9 @@ struct _tls {
int lasterror; int lasterror;
}; };
static void _tls_set_error(tls_t *tls, int error);
static void _tls_log_error(xmpp_ctx_t *ctx);
void tls_initialize(void) void tls_initialize(void)
{ {
SSL_library_init(); SSL_library_init();
@@ -62,23 +66,32 @@ tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock)
tls->ctx = ctx; tls->ctx = ctx;
tls->sock = sock; tls->sock = sock;
tls->ssl_ctx = SSL_CTX_new(SSLv23_client_method()); tls->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
if (tls->ssl_ctx == NULL)
goto err;
SSL_CTX_set_client_cert_cb(tls->ssl_ctx, NULL); SSL_CTX_set_client_cert_cb(tls->ssl_ctx, NULL);
SSL_CTX_set_mode (tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); SSL_CTX_set_mode (tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_verify (tls->ssl_ctx, SSL_VERIFY_NONE, NULL); SSL_CTX_set_verify (tls->ssl_ctx, SSL_VERIFY_NONE, NULL);
tls->ssl = SSL_new(tls->ssl_ctx); tls->ssl = SSL_new(tls->ssl_ctx);
if (tls->ssl == NULL)
goto err_free_ctx;
ret = SSL_set_fd(tls->ssl, sock); ret = SSL_set_fd(tls->ssl, sock);
if (ret <= 0) { if (ret <= 0)
tls->lasterror = SSL_get_error(tls->ssl, ret); goto err_free_ssl;
tls_error(tls);
tls_free(tls);
tls = NULL;
}
} }
return tls; return tls;
err_free_ssl:
SSL_free(tls->ssl);
err_free_ctx:
SSL_CTX_free(tls->ssl_ctx);
err:
xmpp_free(ctx, tls);
_tls_log_error(ctx);
return NULL;
} }
void tls_free(tls_t *tls) void tls_free(tls_t *tls)
@@ -124,7 +137,7 @@ int tls_start(tls_t *tls)
/* success or fatal error */ /* success or fatal error */
break; break;
} }
tls->lasterror = error; _tls_set_error(tls, error);
return ret <= 0 ? 0 : 1; return ret <= 0 ? 0 : 1;
@@ -135,7 +148,7 @@ int tls_stop(tls_t *tls)
int ret; int ret;
ret = SSL_shutdown(tls->ssl); ret = SSL_shutdown(tls->ssl);
tls->lasterror = ret <= 0 ? SSL_get_error(tls->ssl, ret) : 0; _tls_set_error(tls, ret < 0 ? SSL_get_error(tls->ssl, ret) : 0);
return ret <= 0 ? 0 : 1; return ret <= 0 ? 0 : 1;
} }
@@ -155,21 +168,21 @@ int tls_pending(tls_t *tls)
int tls_read(tls_t *tls, void * const buff, const size_t len) int tls_read(tls_t *tls, void * const buff, const size_t len)
{ {
int ret = SSL_read(tls->ssl, buff, len); int ret;
ret = SSL_read(tls->ssl, buff, len);
_tls_set_error(tls, ret <= 0 ? SSL_get_error(tls->ssl, ret) : 0);
if (ret <= 0) {
tls->lasterror = SSL_get_error(tls->ssl, ret);
}
return ret; return ret;
} }
int tls_write(tls_t *tls, const void * const buff, const size_t len) int tls_write(tls_t *tls, const void * const buff, const size_t len)
{ {
int ret = SSL_write(tls->ssl, buff, len); int ret;
ret = SSL_write(tls->ssl, buff, len);
_tls_set_error(tls, ret <= 0 ? SSL_get_error(tls->ssl, ret) : 0);
if (ret <= 0) {
tls->lasterror = SSL_get_error(tls->ssl, ret);
}
return ret; return ret;
} }
@@ -177,3 +190,25 @@ int tls_clear_pending_write(tls_t *tls)
{ {
return 0; return 0;
} }
static void _tls_set_error(tls_t *tls, int error)
{
if (error != 0 && !tls_is_recoverable(error)) {
_tls_log_error(tls->ctx);
}
tls->lasterror = error;
}
static void _tls_log_error(xmpp_ctx_t *ctx)
{
unsigned long e;
char buf[256];
do {
e = ERR_get_error();
if (e != 0) {
ERR_error_string_n(e, buf, sizeof(buf));
xmpp_debug(ctx, "tls", "%s", buf);
}
} while (e != 0);
}