16 #include <openssl/ssl.h> 17 #include <openssl/conf.h> 18 #include <openssl/err.h> 19 #ifdef HAVE_OPENSSL_ASYNC 20 #include <openssl/async.h> 24 #include <vpp/app/version.h> 29 #define MAX_CRYPTO_LEN 16 44 (*ctx)->ctx.c_thread_index = thread_index;
47 (*ctx)->openssl_ctx_index = ctx - tm->
ctx_pool[thread_index];
48 return ((*ctx)->openssl_ctx_index);
57 SSL_shutdown (oc->
ssl);
110 u32 deq_max, deq_now;
141 u32 enq_max, deq_now;
145 if (BIO_ctrl_pending (oc->
rbio) <= 0)
175 #ifdef HAVE_OPENSSL_ASYNC 177 vpp_ssl_async_process_event (
tls_ctx_t * ctx,
186 SSL_set_async_callback_arg (oc->
ssl, (
void *) engine_cb->
arg);
212 #ifdef HAVE_OPENSSL_ASYNC 217 while (SSL_in_init (oc->
ssl))
228 #ifdef HAVE_OPENSSL_ASYNC 230 vpp_ssl_async_process_event (ctx, myself);
233 rv = SSL_do_handshake (oc->
ssl);
234 err = SSL_get_error (oc->
ssl, rv);
236 #ifdef HAVE_OPENSSL_ASYNC 237 if (err == SSL_ERROR_WANT_ASYNC)
239 SSL_get_async_status (oc->
ssl, &estatus);
241 if (estatus == ASYNC_STATUS_EAGAIN)
243 vpp_ssl_async_retry_func (ctx, myself);
248 if (err != SSL_ERROR_WANT_WRITE)
250 if (err == SSL_ERROR_SSL)
253 ERR_error_string (ERR_get_error (), buf);
260 SSL_state_string_long (oc->
ssl));
262 if (SSL_in_init (oc->
ssl))
268 if (!SSL_is_server (oc->
ssl))
273 if ((rv = SSL_get_verify_result (oc->
ssl)) != X509_V_OK)
275 TLS_DBG (1,
" failed verify: %s\n",
276 X509_verify_cert_error_string (rv));
294 TLS_DBG (1,
"Handshake for %u complete. TLS cipher is %s",
303 int wrote = 0, rv, read, max_buf = 100 *
TLS_CHUNK_SIZE, max_space;
304 u32 enq_max, deq_max, deq_now, to_write;
313 max_space = max_buf - BIO_ctrl_pending (oc->
rbio);
314 max_space = (max_space < 0) ? 0 : max_space;
340 if (BIO_ctrl_pending (oc->
rbio) <= 0)
363 if (read < enq_max && BIO_ctrl_pending (oc->
rbio) > 0)
371 if (BIO_ctrl_pending (oc->
rbio) > 0)
380 int read, wrote = 0, max_space, max_buf = 100 *
TLS_CHUNK_SIZE, rv;
382 u32 deq_max, enq_max, deq_now, to_read;
394 max_space = max_buf - BIO_ctrl_pending (oc->
wbio);
395 max_space = max_space < 0 ? 0 : max_space;
396 deq_now =
clib_min (deq_max, max_space);
423 if (BIO_ctrl_pending (oc->
wbio) <= 0)
443 if (read < enq_max && BIO_ctrl_pending (oc->
wbio) > 0)
452 if (BIO_ctrl_pending (oc->
wbio) > 0)
461 long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
465 const SSL_METHOD *method;
467 #ifdef HAVE_OPENSSL_ASYNC 471 method = SSLv23_client_method ();
474 TLS_DBG (1,
"SSLv23_method returned null");
478 oc->
ssl_ctx = SSL_CTX_new (method);
481 TLS_DBG (1,
"SSL_CTX_new returned null");
485 SSL_CTX_set_ecdh_auto (oc->
ssl_ctx, 1);
486 SSL_CTX_set_mode (oc->
ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
487 #ifdef HAVE_OPENSSL_ASYNC 489 SSL_CTX_set_mode (oc->
ssl_ctx, SSL_MODE_ASYNC);
491 rv = SSL_CTX_set_cipher_list (oc->
ssl_ctx, (
const char *) om->
ciphers);
494 TLS_DBG (1,
"Couldn't set cipher");
498 SSL_CTX_set_options (oc->
ssl_ctx, flags);
504 TLS_DBG (1,
"Couldn't initialize ssl struct");
508 oc->
rbio = BIO_new (BIO_s_mem ());
509 oc->
wbio = BIO_new (BIO_s_mem ());
511 BIO_set_mem_eof_return (oc->
rbio, -1);
512 BIO_set_mem_eof_return (oc->
wbio, -1);
515 SSL_set_connect_state (oc->
ssl);
520 TLS_DBG (1,
"Couldn't set hostname");
527 TLS_DBG (1,
"Initiating handshake for [%u]%u", ctx->c_thread_index,
533 rv = SSL_do_handshake (oc->
ssl);
534 err = SSL_get_error (oc->
ssl, rv);
536 #ifdef HAVE_OPENSSL_ASYNC 537 if (err == SSL_ERROR_WANT_ASYNC)
540 vpp_ssl_async_process_event (ctx, handler);
544 if (err != SSL_ERROR_WANT_WRITE)
548 TLS_DBG (2,
"tls state for [%u]%u is su", ctx->c_thread_index,
557 const SSL_METHOD *method;
567 long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
577 TLS_DBG (1,
"tls cert and/or key not configured %d",
578 lctx->parent_app_wrk_index);
582 method = SSLv23_method ();
583 ssl_ctx = SSL_CTX_new (method);
590 SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
591 #ifdef HAVE_OPENSSL_ASYNC 593 SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ASYNC);
596 SSL_CTX_set_options (ssl_ctx, flags);
597 SSL_CTX_set_ecdh_auto (ssl_ctx, 1);
599 rv = SSL_CTX_set_cipher_list (ssl_ctx, (
const char *) om->
ciphers);
602 TLS_DBG (1,
"Couldn't set cipher");
609 cert_bio = BIO_new (BIO_s_mem ());
611 srvcert = PEM_read_bio_X509 (cert_bio,
NULL,
NULL,
NULL);
617 SSL_CTX_use_certificate (ssl_ctx, srvcert);
620 cert_bio = BIO_new (BIO_s_mem ());
622 pkey = PEM_read_bio_PrivateKey (cert_bio,
NULL,
NULL,
NULL);
628 SSL_CTX_use_PrivateKey (ssl_ctx, pkey);
638 lctx->tls_ssl_ctx = olc_index;
650 olc_index = lctx->tls_ssl_ctx;
654 EVP_PKEY_free (olc->
pkey);
666 u32 olc_index = ctx->tls_ssl_ctx;
670 #ifdef HAVE_OPENSSL_ASYNC 680 TLS_DBG (1,
"Couldn't initialize ssl struct");
684 oc->
rbio = BIO_new (BIO_s_mem ());
685 oc->
wbio = BIO_new (BIO_s_mem ());
687 BIO_set_mem_eof_return (oc->
rbio, -1);
688 BIO_set_mem_eof_return (oc->
wbio, -1);
691 SSL_set_accept_state (oc->
ssl);
693 TLS_DBG (1,
"Initiating handshake for [%u]%u", ctx->c_thread_index,
699 rv = SSL_do_handshake (oc->
ssl);
700 err = SSL_get_error (oc->
ssl, rv);
702 #ifdef HAVE_OPENSSL_ASYNC 703 if (err == SSL_ERROR_WANT_ASYNC)
706 vpp_ssl_async_process_event (ctx, handler);
710 if (err != SSL_ERROR_WANT_WRITE)
714 TLS_DBG (2,
"tls state for [%u]%u is su", ctx->c_thread_index,
725 return SSL_is_init_finished (mc->
ssl);
753 clib_warning (
"Could not initialize TLS CA certificates");
771 cert_bio = BIO_new (BIO_s_mem ());
773 testcert = PEM_read_bio_X509 (cert_bio,
NULL,
NULL,
NULL);
779 X509_STORE_add_cert (om->
cert_store, testcert);
782 return (rv < 0 ? -1 : 0);
799 om->
ciphers[
i] = toupper (ciphers[i]);
820 SSL_load_error_strings ();
836 (
"ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH");
841 #ifdef HAVE_OPENSSL_ASYNC 847 char *engine_name =
NULL;
848 char *engine_alg =
NULL;
849 char *ciphers =
NULL;
850 u8 engine_name_set = 0;
858 (0,
"engine has started, and no config is accepted");
863 if (
unformat (input,
"engine %s", &engine_name))
872 else if (
unformat (input,
"alg %s", &engine_alg))
875 engine_alg[i] = toupper (engine_alg[i]);
877 else if (
unformat (input,
"ciphers %s", &ciphers))
887 if (!engine_name_set)
907 .path =
"tls openssl set",
908 .short_help =
"tls openssl set [engine <engine name>] [alg [algorithm] [async]",
909 .function = tls_openssl_set_command_fn,
919 .version = VPP_BUILD_VER,
920 .description =
"Transport Layer Security (TLS) Engine, OpenSSL Based",
tls_main_t * vnet_tls_get_main(void)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
openssl_listen_ctx_t * lctx_pool
int(* callback)(SSL *ssl, void *arg)
static int tls_openssl_set_ciphers(char *ciphers)
static u8 openssl_handshake_is_over(tls_ctx_t *ctx)
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
void openssl_async_node_enable_disable(u8 is_en)
int tls_add_vpp_q_builtin_rx_evt(session_t *s)
static u32 openssl_ctx_alloc(void)
static void openssl_listen_ctx_free(openssl_listen_ctx_t *lctx)
int tls_async_openssl_callback(SSL *s, void *evt)
static void openssl_ctx_free(tls_ctx_t *ctx)
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
static u32 svm_fifo_max_enqueue(svm_fifo_t *f)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static u8 * svm_fifo_tail(svm_fifo_t *f)
struct _svm_fifo svm_fifo_t
static void svm_fifo_enqueue_nocopy(svm_fifo_t *f, u32 bytes)
Advance tail pointer.
#define VLIB_INIT_FUNCTION(x)
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
int openssl_engine_register(char *engine_name, char *algorithm)
#define clib_error_return(e, args...)
static int openssl_stop_listen(tls_ctx_t *lctx)
static u32 svm_fifo_max_write_chunk(svm_fifo_t *f)
Max contiguous chunk of data that can be written.
#define vlib_call_init_function(vm, x)
static u8 * svm_fifo_head(svm_fifo_t *f)
int tls_add_vpp_q_builtin_tx_evt(session_t *s)
static u32 svm_fifo_max_read_chunk(svm_fifo_t *f)
Max contiguous chunk of data that can be read.
int tls_init_ca_chain(void)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
int vpp_add_async_run_event(tls_ctx_t *ctx, openssl_resume_handler *handler)
static session_t * session_get_from_handle(session_handle_t handle)
int tls_notify_app_connected(tls_ctx_t *ctx, u8 is_failed)
tls_ctx_t * openssl_ctx_get(u32 ctx_index)
static const char test_srv_crt_rsa[]
static int openssl_ctx_init_client(tls_ctx_t *ctx)
static_always_inline uword vlib_get_thread_index(void)
openssl_ctx_t *** ctx_pool
#define clib_warning(format, args...)
#define SESSION_INVALID_HANDLE
static int openssl_ctx_write(tls_ctx_t *ctx, session_t *app_session)
static int openssl_try_handshake_write(openssl_ctx_t *oc, session_t *tls_session)
static int openssl_ctx_read(tls_ctx_t *ctx, session_t *tls_session)
static openssl_main_t openssl_main
int tls_add_vpp_q_tx_evt(session_t *s)
void tls_register_engine(const tls_engine_vft_t *vft, tls_engine_type_t type)
application_t * application_get(u32 app_index)
#define VLIB_CLI_COMMAND(x,...)
#define pool_put_index(p, i)
Free pool element with given index.
int openssl_resume_handler(tls_ctx_t *ctx, session_t *tls_session)
static clib_error_t * tls_openssl_init(vlib_main_t *vm)
u8 * tls_key
PEM encoded key.
static void * clib_mem_alloc(uword size)
tls_ctx_t * openssl_ctx_get_w_thread(u32 ctx_index, u8 thread_index)
static int openssl_ctx_init_server(tls_ctx_t *ctx)
int svm_fifo_dequeue_drop(svm_fifo_t *f, u32 max_bytes)
app_worker_t * app_worker_get(u32 wrk_index)
openssl_tls_callback_t * vpp_add_async_pending_event(tls_ctx_t *ctx, openssl_resume_handler *handler)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static int openssl_start_listen(tls_ctx_t *lctx)
int openssl_ctx_handshake_rx(tls_ctx_t *ctx, session_t *tls_session)
int tls_notify_app_accept(tls_ctx_t *ctx)
u32 app_index
Index of owning app.
void tls_notify_app_enqueue(tls_ctx_t *ctx, session_t *app_session)
static int openssl_try_handshake_read(openssl_ctx_t *oc, session_t *tls_session)
static vlib_thread_main_t * vlib_get_thread_main()
u8 * tls_cert
Certificate to be used for listen sessions.
openssl_listen_ctx_t * openssl_lctx_get(u32 lctx_index)
static u32 openssl_listen_ctx_alloc(void)
static clib_error_t * tls_init(vlib_main_t *vm)
#define TLS_DBG(_lvl, _fmt, _args...)
static const u32 test_srv_crt_rsa_len