You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/debian/patches/upstream/tls-Add-and-apply-tls_opens...

166 lines
5.5 KiB

From: Xenofon Karamanos <xk@gilawa.com>
Date: Thu, 19 Oct 2023 12:18:38 +0000
Subject: tls: Add and apply tls_openssl_clear_errors function
(cherry picked from commit 110ebbafadcc225f4e88749287f06ae29a6cfa2e)
---
src/modules/tls/tls_ct_wrq.c | 3 +++
src/modules/tls/tls_server.c | 11 +++++++++++
src/modules/tls/tls_util.c | 15 +++++++++++++++
src/modules/tls/tls_util.h | 2 ++
4 files changed, 31 insertions(+)
diff --git a/src/modules/tls/tls_ct_wrq.c b/src/modules/tls/tls_ct_wrq.c
index c3b6156..8850e54 100644
--- a/src/modules/tls/tls_ct_wrq.c
+++ b/src/modules/tls/tls_ct_wrq.c
@@ -103,6 +103,7 @@ static int ssl_flush(void* tcp_c, void* error, const void* buf, unsigned size)
if (unlikely(tls_c->state == S_TLS_CONNECTING)) {
n = tls_connect(tcp_c, &ssl_error);
if (unlikely(n>=1)) {
+ tls_openssl_clear_errors();
n = SSL_write(ssl, buf, size);
if (unlikely(n <= 0))
ssl_error = SSL_get_error(ssl, n);
@@ -110,11 +111,13 @@ static int ssl_flush(void* tcp_c, void* error, const void* buf, unsigned size)
} else if (unlikely(tls_c->state == S_TLS_ACCEPTING)) {
n = tls_accept(tcp_c, &ssl_error);
if (unlikely(n>=1)) {
+ tls_openssl_clear_errors();
n = SSL_write(ssl, buf, size);
if (unlikely(n <= 0))
ssl_error = SSL_get_error(ssl, n);
}
} else {
+ tls_openssl_clear_errors();
n = SSL_write(ssl, buf, size);
if (unlikely(n <= 0))
ssl_error = SSL_get_error(ssl, n);
diff --git a/src/modules/tls/tls_server.c b/src/modules/tls/tls_server.c
index 5c039c9..cb66794 100644
--- a/src/modules/tls/tls_server.c
+++ b/src/modules/tls/tls_server.c
@@ -281,6 +281,7 @@ static int tls_complete_init(struct tcp_connection* c)
goto error;
}
memset(data, '\0', sizeof(struct tls_extra_data));
+ tls_openssl_clear_errors();
data->ssl = SSL_new(dom->ctx[process_no]);
data->rwbio = tls_BIO_new_mbuf(0, 0);
data->cfg = cfg;
@@ -467,6 +468,7 @@ int tls_accept(struct tcp_connection *c, int* error)
if (pkey)
SSL_use_PrivateKey(ssl, pkey);
#endif
+ tls_openssl_clear_errors();
ret = SSL_accept(ssl);
if (unlikely(ret == 1)) {
DBG("TLS accept successful\n");
@@ -539,6 +541,7 @@ int tls_connect(struct tcp_connection *c, int* error)
SSL_use_PrivateKey(ssl, pkey);
}
#endif
+ tls_openssl_clear_errors();
ret = SSL_connect(ssl);
if (unlikely(ret == 1)) {
DBG("TLS connect successful\n");
@@ -603,6 +606,7 @@ static int tls_shutdown(struct tcp_connection *c)
goto err;
}
+ tls_openssl_clear_errors();
ret = SSL_shutdown(ssl);
if (ret == 1) {
DBG("TLS shutdown successful\n");
@@ -698,6 +702,7 @@ void tls_h_tcpconn_clean_f(struct tcp_connection *c)
BUG("Bad connection structure\n");
abort();
}
+ tls_openssl_clear_errors();
if (c->extra_data) {
extra = (struct tls_extra_data*)c->extra_data;
SSL_free(extra->ssl);
@@ -851,6 +856,7 @@ redo_wr:
n = tls_connect(c, &ssl_error);
TLS_WR_TRACE("(%p) tls_connect() => %d (err=%d)\n", c, n, ssl_error);
if (unlikely(n>=1)) {
+ tls_openssl_clear_errors();
n = SSL_write(ssl, buf + offs, len - offs);
if (unlikely(n <= 0))
ssl_error = SSL_get_error(ssl, n);
@@ -864,6 +870,7 @@ redo_wr:
n = tls_accept(c, &ssl_error);
TLS_WR_TRACE("(%p) tls_accept() => %d (err=%d)\n", c, n, ssl_error);
if (unlikely(n>=1)) {
+ tls_openssl_clear_errors();
n = SSL_write(ssl, buf + offs, len - offs);
if (unlikely(n <= 0))
ssl_error = SSL_get_error(ssl, n);
@@ -874,6 +881,7 @@ redo_wr:
err_src = "TLS accept:";
}
} else {
+ tls_openssl_clear_errors();
n = SSL_write(ssl, buf + offs, len - offs);
if (unlikely(n <= 0))
ssl_error = SSL_get_error(ssl, n);
@@ -1161,6 +1169,7 @@ continue_ssl_read:
TLS_RD_TRACE("(%p, %p) tls_connect() => %d (err=%d)\n",
c, flags, n, ssl_error);
if (unlikely(n>=1)) {
+ tls_openssl_clear_errors();
n = SSL_read(ssl, r->pos, bytes_free);
} else {
/* tls_connect failed/needs more IO */
@@ -1176,6 +1185,7 @@ continue_ssl_read:
TLS_RD_TRACE("(%p, %p) tls_accept() => %d (err=%d)\n",
c, flags, n, ssl_error);
if (unlikely(n>=1)) {
+ tls_openssl_clear_errors();
n = SSL_read(ssl, r->pos, bytes_free);
} else {
/* tls_accept failed/needs more IO */
@@ -1189,6 +1199,7 @@ continue_ssl_read:
} else {
/* if bytes in then decrypt read buffer into tcpconn req.
* buffer */
+ tls_openssl_clear_errors();
n = SSL_read(ssl, r->pos, bytes_free);
}
/** handle SSL_read() return.
diff --git a/src/modules/tls/tls_util.c b/src/modules/tls/tls_util.c
index 4c976f3..1882666 100644
--- a/src/modules/tls/tls_util.c
+++ b/src/modules/tls/tls_util.c
@@ -97,3 +97,18 @@ void collect_garbage(void)
lock_release(tls_domains_cfg_lock);
}
+/*
+ * Get any leftover errors from OpenSSL and print them.
+ * ERR_get_error() also removes the error from the OpenSSL error stack.
+ * This is useful to call before any SSL_* IO calls to make sure
+ * we don't have any leftover errors from previous calls (OpenSSL docs).
+ */
+void tls_openssl_clear_errors(void)
+{
+ int i;
+ char err[160];
+ while((i = ERR_get_error())) {
+ ERR_error_string(i, err);
+ INFO("clearing leftover error before SSL_* calls: %s", err);
+ }
+}
\ No newline at end of file
diff --git a/src/modules/tls/tls_util.h b/src/modules/tls/tls_util.h
index b1f488e..e92f164 100644
--- a/src/modules/tls/tls_util.h
+++ b/src/modules/tls/tls_util.h
@@ -83,4 +83,6 @@ int shm_asciiz_dup(char** dest, char* val);
*/
void collect_garbage(void);
+void tls_openssl_clear_errors(void);
+
#endif /* _TLS_UTIL_H */