SSL_free (oc->ssl);
+#ifdef HAVE_OPENSSL_ASYNC
+ openssl_evt_free (ctx->evt_index, ctx->c_thread_index);
+#endif
vec_free (ctx->srv_hostname);
pool_put_index (openssl_main.ctx_pool[ctx->c_thread_index],
oc->openssl_ctx_index);
#ifdef HAVE_OPENSSL_ASYNC
static int
-vpp_ssl_async_process_event (tls_ctx_t * ctx,
- openssl_resume_handler * handler)
+openssl_check_async_status (tls_ctx_t * ctx, openssl_resume_handler * handler,
+ session_t * session)
{
openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
- openssl_tls_callback_t *engine_cb;
+ int estatus;
- engine_cb = vpp_add_async_pending_event (ctx, handler);
- if (engine_cb)
+ SSL_get_async_status (oc->ssl, &estatus);
+ if (estatus == ASYNC_STATUS_EAGAIN)
{
- SSL_set_async_callback_arg (oc->ssl, (void *) engine_cb->arg);
- TLS_DBG (2, "set callback to engine %p\n", engine_cb->callback);
+ vpp_tls_async_update_event (ctx, 1);
+ }
+ else
+ {
+ vpp_tls_async_update_event (ctx, 0);
}
- return 0;
-
-}
-
-/* Due to engine busy stat, VPP need to retry later */
-static int
-vpp_ssl_async_retry_func (tls_ctx_t * ctx, openssl_resume_handler * handler)
-{
-
- if (vpp_add_async_run_event (ctx, handler))
- return 1;
- return 0;
+ return 1;
}
static void
openssl_handle_handshake_failure (tls_ctx_t * ctx)
{
+ session_t *app_session;
+
if (SSL_is_server (((openssl_ctx_t *) ctx)->ssl))
{
/*
* Cleanup pre-allocated app session and close transport
*/
- session_free (session_get (ctx->c_s_index, ctx->c_thread_index));
- ctx->no_app_session = 1;
- ctx->c_s_index = SESSION_INVALID_INDEX;
- tls_disconnect_transport (ctx);
+ app_session =
+ session_get_if_valid (ctx->c_s_index, ctx->c_thread_index);
+ if (app_session)
+ {
+ session_free (app_session);
+ ctx->no_app_session = 1;
+ ctx->c_s_index = SESSION_INVALID_INDEX;
+ tls_disconnect_transport (ctx);
+ }
}
else
{
{
openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
int rv = 0, err;
-#ifdef HAVE_OPENSSL_ASYNC
- int estatus;
- openssl_resume_handler *myself;
-#endif
while (SSL_in_init (oc->ssl))
{
ctx->resume = 0;
}
else if (!openssl_try_handshake_read (oc, tls_session))
- {
- break;
- }
-
-#ifdef HAVE_OPENSSL_ASYNC
- myself = openssl_ctx_handshake_rx;
- vpp_ssl_async_process_event (ctx, myself);
-#endif
+ break;
rv = SSL_do_handshake (oc->ssl);
err = SSL_get_error (oc->ssl, rv);
+#ifdef HAVE_OPENSSL_ASYNC
+ if (err == SSL_ERROR_WANT_ASYNC)
+ {
+ openssl_check_async_status (ctx, openssl_ctx_handshake_rx,
+ tls_session);
+ }
+#endif
if (err == SSL_ERROR_SSL)
{
char buf[512];
}
openssl_try_handshake_write (oc, tls_session);
-#ifdef HAVE_OPENSSL_ASYNC
- if (err == SSL_ERROR_WANT_ASYNC)
- {
- SSL_get_async_status (oc->ssl, &estatus);
-
- if (estatus == ASYNC_STATUS_EAGAIN)
- {
- vpp_ssl_async_retry_func (ctx, myself);
- }
- }
-#endif
if (err != SSL_ERROR_WANT_WRITE)
break;
SSL_state_string_long (oc->ssl));
if (SSL_in_init (oc->ssl))
- return 0;
+ return -1;
/*
* Handshake complete
}
else
{
- tls_notify_app_accept (ctx);
+ /* Need to check transport status */
+ if (ctx->is_passive_close)
+ openssl_handle_handshake_failure (ctx);
+ else
+ tls_notify_app_accept (ctx);
}
TLS_DBG (1, "Handshake for %u complete. TLS cipher is %s",
if (PREDICT_FALSE (SSL_in_init (oc->ssl)))
{
- openssl_ctx_handshake_rx (ctx, tls_session);
- return 0;
+ if (openssl_ctx_handshake_rx (ctx, tls_session) < 0)
+ return 0;
+ else
+ goto check_app_fifo;
}
f = tls_session->rx_fifo;
return wrote;
}
svm_fifo_enqueue_nocopy (f, read);
- if (read < enq_max && BIO_ctrl_pending (oc->wbio) > 0)
+ if (read < enq_max && SSL_pending (oc->ssl) > 0)
{
deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max - read);
read = SSL_read (oc->ssl, svm_fifo_tail (f), deq_now);
svm_fifo_enqueue_nocopy (f, read);
}
- tls_notify_app_enqueue (ctx, app_session);
- if (BIO_ctrl_pending (oc->wbio) > 0)
+ /* If handshake just completed, session may still be in accepting state */
+ if (app_session->session_state >= SESSION_STATE_READY)
+ tls_notify_app_enqueue (ctx, app_session);
+ if (SSL_pending (oc->ssl) > 0)
tls_add_vpp_q_builtin_rx_evt (tls_session);
return wrote;
session_t *tls_session;
const SSL_METHOD *method;
int rv, err;
-#ifdef HAVE_OPENSSL_ASYNC
- openssl_resume_handler *handler;
-#endif
method = SSLv23_client_method ();
if (method == NULL)
oc->openssl_ctx_index);
tls_session = session_get_from_handle (ctx->tls_session_handle);
+
+#ifdef HAVE_OPENSSL_ASYNC
+ vpp_tls_async_init_event (ctx, openssl_ctx_handshake_rx, tls_session);
+#endif
while (1)
{
rv = SSL_do_handshake (oc->ssl);
#ifdef HAVE_OPENSSL_ASYNC
if (err == SSL_ERROR_WANT_ASYNC)
{
- handler = (openssl_resume_handler *) openssl_ctx_handshake_rx;
- vpp_ssl_async_process_event (ctx, handler);
+ openssl_check_async_status (ctx, openssl_ctx_handshake_rx,
+ tls_session);
break;
}
#endif
SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
#ifdef HAVE_OPENSSL_ASYNC
if (om->async)
- SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ASYNC);
- SSL_CTX_set_async_callback (ssl_ctx, tls_async_openssl_callback);
+ {
+ SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ASYNC);
+ SSL_CTX_set_async_callback (ssl_ctx, tls_async_openssl_callback);
+ }
#endif
SSL_CTX_set_options (ssl_ctx, flags);
SSL_CTX_set_ecdh_auto (ssl_ctx, 1);
openssl_listen_ctx_t *olc;
session_t *tls_session;
int rv, err;
-#ifdef HAVE_OPENSSL_ASYNC
- openssl_resume_handler *handler;
-#endif
/* Start a new connection */
oc->openssl_ctx_index);
tls_session = session_get_from_handle (ctx->tls_session_handle);
+#ifdef HAVE_OPENSSL_ASYNC
+ vpp_tls_async_init_event (ctx, openssl_ctx_handshake_rx, tls_session);
+#endif
while (1)
{
rv = SSL_do_handshake (oc->ssl);
#ifdef HAVE_OPENSSL_ASYNC
if (err == SSL_ERROR_WANT_ASYNC)
{
- handler = (openssl_resume_handler *) openssl_ctx_handshake_rx;
- vpp_ssl_async_process_event (ctx, handler);
+ openssl_check_async_status (ctx, openssl_ctx_handshake_rx,
+ tls_session);
break;
}
#endif
static int
openssl_transport_close (tls_ctx_t * ctx)
{
+#ifdef HAVE_OPENSSL_ASYNC
+ if (vpp_openssl_is_inflight (ctx))
+ return 0;
+#endif
+
if (!openssl_handshake_is_over (ctx))
{
openssl_handle_handshake_failure (ctx);
return -1;
}
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ rv = X509_STORE_load_file (om->cert_store, tm->ca_cert_path);
+#else
rv = X509_STORE_load_locations (om->cert_store, tm->ca_cert_path, 0);
+#endif
+
if (rv < 0)
{
clib_warning ("failed to load ca certificate");
char *engine_alg = NULL;
char *ciphers = NULL;
u8 engine_name_set = 0;
- int i;
+ int i, async = 0;
/* By present, it is not allowed to configure engine again after running */
if (om->engine_init)
}
else if (unformat (input, "async"))
{
- om->async = 1;
- openssl_async_node_enable_disable (1);
+ async = 1;
}
else if (unformat (input, "alg %s", &engine_alg))
{
if (!engine_name_set)
{
clib_warning ("No engine provided! \n");
- om->async = 0;
+ async = 0;
}
else
{
- if (openssl_engine_register (engine_name, engine_alg) < 0)
+ vnet_session_enable_disable (vm, 1);
+ if (openssl_engine_register (engine_name, engine_alg, async) < 0)
{
- return clib_error_return (0, "failed to register %s polling",
+ return clib_error_return (0, "Failed to register %s polling",
engine_name);
}
+ else
+ {
+ vlib_cli_output (vm, "Successfully register engine %s\n",
+ engine_name);
+ }
}
+ om->async = async;
return 0;
}