tls: handle read write ssl errors 40/35440/2
authorFlorin Coras <fcoras@cisco.com>
Fri, 25 Feb 2022 00:35:26 +0000 (16:35 -0800)
committerDave Barach <openvpp@barachs.net>
Mon, 28 Feb 2022 21:04:14 +0000 (21:04 +0000)
Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: If5eed7dac4951f0510a4b4b092f66f44d0d3cacd

src/plugins/tlsopenssl/tls_openssl.c
src/vnet/tls/tls.c
src/vnet/tls/tls.h

index 2befac0..74b8142 100644 (file)
@@ -155,6 +155,10 @@ openssl_lctx_get (u32 lctx_index)
   return pool_elt_at_index (openssl_main.lctx_pool, lctx_index);
 }
 
+#define ossl_check_err_is_fatal(_ssl, _rv)                                    \
+  if (PREDICT_FALSE (_rv < 0 && SSL_get_error (_ssl, _rv) == SSL_ERROR_SSL))  \
+    return -1;
+
 static int
 openssl_read_from_ssl_into_fifo (svm_fifo_t * f, SSL * ssl)
 {
@@ -174,7 +178,10 @@ openssl_read_from_ssl_into_fifo (svm_fifo_t * f, SSL * ssl)
   /* Return early if we can't read anything */
   read = SSL_read (ssl, fs[0].data, fs[0].len);
   if (read <= 0)
-    return 0;
+    {
+      ossl_check_err_is_fatal (ssl, read);
+      return 0;
+    }
 
   for (i = 1; i < n_fs; i++)
     {
@@ -182,7 +189,10 @@ openssl_read_from_ssl_into_fifo (svm_fifo_t * f, SSL * ssl)
       read += rv > 0 ? rv : 0;
 
       if (rv < (int) fs[i].len)
-       break;
+       {
+         ossl_check_err_is_fatal (ssl, rv);
+         break;
+       }
     }
 
   svm_fifo_enqueue_nocopy (f, read);
@@ -206,7 +216,10 @@ openssl_write_from_fifo_into_ssl (svm_fifo_t *f, SSL *ssl, u32 max_len)
       rv = SSL_write (ssl, fs[i].data, fs[i].len);
       wrote += (rv > 0) ? rv : 0;
       if (rv < (int) fs[i].len)
-       break;
+       {
+         ossl_check_err_is_fatal (ssl, rv);
+         break;
+       }
       i++;
     }
 
@@ -402,6 +415,14 @@ openssl_ctx_write_tls (tls_ctx_t *ctx, session_t *app_session,
     goto check_tls_fifo;
 
   wrote = openssl_write_from_fifo_into_ssl (f, oc->ssl, deq_max);
+
+  /* Unrecoverable protocol error. Reset connection */
+  if (PREDICT_FALSE (wrote < 0))
+    {
+      tls_notify_app_io_error (ctx);
+      return 0;
+    }
+
   if (!wrote)
     goto check_tls_fifo;
 
@@ -518,6 +539,13 @@ openssl_ctx_read_tls (tls_ctx_t *ctx, session_t *tls_session)
 
   read = openssl_read_from_ssl_into_fifo (f, oc->ssl);
 
+  /* Unrecoverable protocol error. Reset connection */
+  if (PREDICT_FALSE (read < 0))
+    {
+      tls_notify_app_io_error (ctx);
+      return 0;
+    }
+
   /* If handshake just completed, session may still be in accepting state */
   if (read && app_session->session_state >= SESSION_STATE_READY)
     tls_notify_app_enqueue (ctx, app_session);
index b91282c..54bb739 100644 (file)
@@ -399,6 +399,16 @@ tls_ctx_handshake_is_over (tls_ctx_t * ctx)
   return tls_vfts[ctx->tls_ctx_engine].ctx_handshake_is_over (ctx);
 }
 
+void
+tls_notify_app_io_error (tls_ctx_t *ctx)
+{
+  ASSERT (tls_ctx_handshake_is_over (ctx));
+
+  session_transport_reset_notify (&ctx->connection);
+  session_transport_closed_notify (&ctx->connection);
+  tls_disconnect_transport (ctx);
+}
+
 void
 tls_session_reset_callback (session_t * s)
 {
index 4e2fabd..54798e0 100644 (file)
@@ -137,6 +137,7 @@ int tls_add_vpp_q_builtin_rx_evt (session_t * s);
 int tls_notify_app_accept (tls_ctx_t * ctx);
 int tls_notify_app_connected (tls_ctx_t * ctx, session_error_t err);
 void tls_notify_app_enqueue (tls_ctx_t * ctx, session_t * app_session);
+void tls_notify_app_io_error (tls_ctx_t *ctx);
 void tls_disconnect_transport (tls_ctx_t * ctx);
 #endif /* SRC_VNET_TLS_TLS_H_ */