|
FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
|
Go to the documentation of this file.
16 #include <openssl/ssl.h>
17 #include <openssl/conf.h>
18 #include <openssl/err.h>
20 #ifdef HAVE_OPENSSL_ASYNC
21 #include <openssl/async.h>
25 #include <vpp/app/version.h>
31 #define MAX_CRYPTO_LEN 64
50 return ((*ctx)->openssl_ctx_index);
65 if (!
ctx->is_migrated)
67 if (SSL_is_init_finished (oc->
ssl) && !
ctx->is_passive_close)
68 SSL_shutdown (oc->
ssl);
73 #ifdef HAVE_OPENSSL_ASYNC
109 sh = (*oc)->ctx.tls_session_handle;
113 return ((*oc)->openssl_ctx_index);
161 int read,
rv, n_fs,
i;
162 const int n_segs = 2;
175 read = SSL_read (ssl, fs[0].
data, fs[0].
len);
179 for (
i = 1;
i < n_fs;
i++)
182 read +=
rv > 0 ?
rv : 0;
196 int wrote = 0,
rv,
i = 0,
len;
197 const int n_segs = 2;
204 while (wrote <
len &&
i < n_segs)
207 wrote += (
rv > 0) ?
rv : 0;
219 #ifdef HAVE_OPENSSL_ASYNC
227 SSL_get_async_status (oc->
ssl, &estatus);
228 if (estatus == ASYNC_STATUS_EAGAIN)
258 ctx->no_app_session = 1;
278 while (SSL_in_init (oc->
ssl))
287 rv = SSL_do_handshake (oc->
ssl);
288 err = SSL_get_error (oc->
ssl,
rv);
290 #ifdef HAVE_OPENSSL_ASYNC
291 if (err == SSL_ERROR_WANT_ASYNC)
297 if (err == SSL_ERROR_SSL)
300 ERR_error_string (ERR_get_error (),
buf);
307 if (err != SSL_ERROR_WANT_WRITE && err != SSL_ERROR_WANT_READ)
311 SSL_state_string_long (oc->
ssl));
313 if (SSL_in_init (oc->
ssl))
319 if (!SSL_is_server (oc->
ssl))
324 if ((
rv = SSL_get_verify_result (oc->
ssl)) != X509_V_OK)
326 TLS_DBG (1,
" failed verify: %s\n",
327 X509_verify_cert_error_string (
rv));
332 if (
ctx->srv_hostname)
343 if (
ctx->is_passive_close)
358 TLS_DBG (1,
"Handshake for %u complete. TLS cipher is %s",
415 if (
space < wrote + enq_buf)
423 app_session->
flags |= SESSION_F_CUSTOM_TX;
434 u32 read = 0, to_deq, dgram_sz, enq_max;
463 hdr.data_length,
buf);
467 wrote = SSL_write (oc->
ssl,
buf,
rv);
493 if (
ctx->tls_type == TRANSPORT_PROTO_TLS)
519 if (read && app_session->
session_state >= SESSION_STATE_READY)
522 if ((SSL_pending (oc->
ssl) > 0) ||
593 if (
ctx->tls_type == TRANSPORT_PROTO_TLS)
602 long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
605 const SSL_METHOD *method;
608 method =
ctx->tls_type == TRANSPORT_PROTO_TLS ? SSLv23_client_method () :
609 DTLS_client_method ();
612 TLS_DBG (1,
"(D)TLS_method returned null");
616 oc->
ssl_ctx = SSL_CTX_new (method);
619 TLS_DBG (1,
"SSL_CTX_new returned null");
623 SSL_CTX_set_ecdh_auto (oc->
ssl_ctx, 1);
624 SSL_CTX_set_mode (oc->
ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
625 #ifdef HAVE_OPENSSL_ASYNC
627 SSL_CTX_set_mode (oc->
ssl_ctx, SSL_MODE_ASYNC);
632 TLS_DBG (1,
"Couldn't set cipher");
642 TLS_DBG (1,
"Couldn't initialize ssl struct");
646 if (
ctx->tls_type == TRANSPORT_PROTO_TLS)
658 SSL_set_connect_state (oc->
ssl);
660 rv = SSL_set_tlsext_host_name (oc->
ssl,
ctx->srv_hostname);
663 TLS_DBG (1,
"Couldn't set hostname");
670 TLS_DBG (1,
"Initiating handshake for [%u]%u",
ctx->c_thread_index,
673 #ifdef HAVE_OPENSSL_ASYNC
679 rv = SSL_do_handshake (oc->
ssl);
680 err = SSL_get_error (oc->
ssl,
rv);
681 #ifdef HAVE_OPENSSL_ASYNC
682 if (err == SSL_ERROR_WANT_ASYNC)
689 if (err != SSL_ERROR_WANT_WRITE)
693 TLS_DBG (2,
"tls state for [%u]%u is su",
ctx->c_thread_index,
701 const SSL_METHOD *method;
711 long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
718 if (!ckpair->
cert || !ckpair->
key)
720 TLS_DBG (1,
"tls cert and/or key not configured %d",
721 lctx->parent_app_wrk_index);
725 method = lctx->
tls_type == TRANSPORT_PROTO_TLS ? SSLv23_server_method () :
726 DTLS_server_method ();
727 ssl_ctx = SSL_CTX_new (method);
734 SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
735 #ifdef HAVE_OPENSSL_ASYNC
738 SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ASYNC);
742 SSL_CTX_set_options (ssl_ctx,
flags);
743 SSL_CTX_set_ecdh_auto (ssl_ctx, 1);
745 rv = SSL_CTX_set_cipher_list (ssl_ctx, (
const char *) om->
ciphers);
748 TLS_DBG (1,
"Couldn't set cipher");
755 cert_bio = BIO_new (BIO_s_mem ());
757 srvcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
763 SSL_CTX_use_certificate (ssl_ctx, srvcert);
766 cert_bio = BIO_new (BIO_s_mem ());
768 pkey = PEM_read_bio_PrivateKey (cert_bio, NULL, NULL, NULL);
774 SSL_CTX_use_PrivateKey (ssl_ctx, pkey);
784 lctx->tls_ssl_ctx = olc_index;
796 olc_index = lctx->tls_ssl_ctx;
800 EVP_PKEY_free (olc->
pkey);
812 u32 olc_index =
ctx->tls_ssl_ctx;
822 TLS_DBG (1,
"Couldn't initialize ssl struct");
826 if (
ctx->tls_type == TRANSPORT_PROTO_TLS)
838 SSL_set_accept_state (oc->
ssl);
840 TLS_DBG (1,
"Initiating handshake for [%u]%u",
ctx->c_thread_index,
843 #ifdef HAVE_OPENSSL_ASYNC
849 rv = SSL_do_handshake (oc->
ssl);
850 err = SSL_get_error (oc->
ssl,
rv);
851 #ifdef HAVE_OPENSSL_ASYNC
852 if (err == SSL_ERROR_WANT_ASYNC)
859 if (err != SSL_ERROR_WANT_WRITE)
863 TLS_DBG (2,
"tls state for [%u]%u is su",
ctx->c_thread_index,
874 return SSL_is_init_finished (mc->
ssl);
880 #ifdef HAVE_OPENSSL_ASYNC
902 if (BIO_ctrl_pending (oc->
rbio) <= 0
940 clib_warning (
"Could not initialize TLS CA certificates");
950 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
963 cert_bio = BIO_new (BIO_s_mem ());
965 testcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
971 X509_STORE_add_cert (om->
cert_store, testcert);
974 return (
rv < 0 ? -1 : 0);
1009 SSL_library_init ();
1010 SSL_load_error_strings ();
1021 for (
i = 0;
i < num_threads;
i++)
1032 (
"ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH");
1043 #ifdef HAVE_OPENSSL_ASYNC
1049 char *engine_name = NULL;
1050 char *engine_alg = NULL;
1051 char *ciphers = NULL;
1052 u8 engine_name_set = 0;
1060 (0,
"engine has started, and no config is accepted");
1065 if (
unformat (input,
"engine %s", &engine_name))
1067 engine_name_set = 1;
1069 else if (
unformat (input,
"async"))
1073 else if (
unformat (input,
"alg %s", &engine_alg))
1076 engine_alg[
i] = toupper (engine_alg[
i]);
1078 else if (
unformat (input,
"ciphers %s", &ciphers))
1088 if (!engine_name_set)
1115 .path =
"tls openssl set",
1116 .short_help =
"tls openssl set [engine <engine name>] [alg [algorithm] [async]",
1117 .function = tls_openssl_set_command_fn,
1124 .version = VPP_BUILD_VER,
1125 .description =
"Transport Layer Security (TLS) Engine, OpenSSL Based",
int svm_fifo_segments(svm_fifo_t *f, u32 offset, svm_fifo_seg_t *fs, u32 n_segs, u32 max_bytes)
Get pointers to fifo chunks data in svm_fifo_seg_t array.
static u32 svm_fifo_size(svm_fifo_t *f)
int session_dequeue_notify(session_t *s)
static u32 openssl_listen_ctx_alloc(void)
openssl_listen_ctx_t * openssl_lctx_get(u32 lctx_index)
u32 session_index
Index in thread pool where session was allocated.
int tls_notify_app_connected(tls_ctx_t *ctx, session_error_t err)
#define clib_memcpy(d, s, n)
int vpp_tls_async_update_event(tls_ctx_t *ctx, int eagain)
static int openssl_ctx_write_tls(tls_ctx_t *ctx, session_t *app_session, transport_send_params_t *sp)
static int openssl_start_listen(tls_ctx_t *lctx)
void session_transport_closing_notify(transport_connection_t *tc)
Notification from transport that connection is being closed.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static int openssl_ctx_read_dtls(tls_ctx_t *ctx, session_t *us)
static clib_error_t * tls_openssl_init(vlib_main_t *vm)
int openssl_engine_register(char *engine_name, char *algorithm, int async)
int svm_fifo_peek(svm_fifo_t *f, u32 offset, u32 len, u8 *dst)
Peek data from fifo.
static void clib_mem_free(void *p)
static u8 svm_fifo_needs_deq_ntf(svm_fifo_t *f, u32 n_last_deq)
Check if fifo needs dequeue notification.
int svm_fifo_fill_chunk_list(svm_fifo_t *f)
Ensure the whole fifo size is writeable.
#define clib_error_return(e, args...)
int svm_fifo_provision_chunks(svm_fifo_t *f, svm_fifo_seg_t *fs, u32 n_segs, u32 len)
Provision and return chunks for number of bytes requested.
int tls_notify_app_accept(tls_ctx_t *ctx)
void tls_notify_app_enqueue(tls_ctx_t *ctx, session_t *app_session)
#define SESSION_INVALID_INDEX
transport_proto_t tls_type
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
BIO * BIO_new_tls(session_handle_t sh)
void session_transport_closed_notify(transport_connection_t *tc)
Notification from transport that it is closed.
int vpp_openssl_is_inflight(tls_ctx_t *ctx)
openssl_ctx_t *** ctx_pool
static int openssl_ctx_read(tls_ctx_t *ctx, session_t *ts)
int tls_openssl_set_ciphers(char *ciphers)
void session_free(session_t *s)
#define pool_put_index(p, i)
Free pool element with given index.
#define SESSION_CONN_HDR_LEN
void tls_disconnect_transport(tls_ctx_t *ctx)
static u32 openssl_ctx_alloc_w_thread(u32 thread_index)
struct _svm_fifo svm_fifo_t
static void openssl_ctx_free(tls_ctx_t *ctx)
static void openssl_handle_handshake_failure(tls_ctx_t *ctx)
@ TRANSPORT_SND_F_DESCHED
@ SVM_FIFO_WANT_DEQ_NOTIF
Notify on dequeue.
#define TLS_DBG(_lvl, _fmt, _args...)
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
int tls_add_vpp_q_builtin_rx_evt(session_t *s)
static int openssl_transport_close(tls_ctx_t *ctx)
static void openssl_confirm_app_close(tls_ctx_t *ctx)
void svm_fifo_enqueue_nocopy(svm_fifo_t *f, u32 len)
Advance tail.
static_always_inline uword vlib_get_thread_index(void)
static u8 openssl_handshake_is_over(tls_ctx_t *ctx)
int svm_fifo_enqueue_segments(svm_fifo_t *f, const svm_fifo_seg_t segs[], u32 n_segs, u8 allow_partial)
Enqueue array of svm_fifo_seg_t in order.
#define TLSO_MIN_ENQ_SPACE
static int openssl_ctx_write_dtls(tls_ctx_t *ctx, session_t *app_session, transport_send_params_t *sp)
static int openssl_ctx_init_client(tls_ctx_t *ctx)
sll srl srl sll sra u16x4 i
int svm_fifo_dequeue_drop(svm_fifo_t *f, u32 len)
Dequeue and drop bytes from fifo.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static session_t * session_get_from_handle(session_handle_t handle)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
int vpp_tls_async_init_event(tls_ctx_t *ctx, openssl_resume_handler *handler, session_t *session)
int openssl_ctx_handshake_rx(tls_ctx_t *ctx, session_t *tls_session)
#define VLIB_CLI_COMMAND(x,...)
openssl_listen_ctx_t * lctx_pool
int openssl_evt_free(int event_index, u8 thread_index)
static session_t * session_get(u32 si, u32 thread_index)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
int tls_async_openssl_callback(SSL *s, void *cb_arg)
static int openssl_stop_listen(tls_ctx_t *lctx)
static int openssl_ctx_init_server(tls_ctx_t *ctx)
#define vec_free(V)
Free vector's memory (no header).
const static tls_engine_vft_t openssl_engine
description No buffer space
static int openssl_read_from_ssl_into_fifo(svm_fifo_t *f, SSL *ssl)
static u32 svm_fifo_max_enqueue_prod(svm_fifo_t *f)
Maximum number of bytes that can be enqueued into fifo.
static const char test_srv_crt_rsa[]
tls_main_t * vnet_tls_get_main(void)
openssl_main_t openssl_main
BIO * BIO_new_dtls(session_handle_t sh)
static session_t * session_get_if_valid(u64 si, u32 thread_index)
#define VLIB_INIT_FUNCTION(x)
static int openssl_ctx_write(tls_ctx_t *ctx, session_t *app_session, transport_send_params_t *sp)
static u32 openssl_ctx_attach(u32 thread_index, void *ctx_ptr)
static void * openssl_ctx_detach(tls_ctx_t *ctx)
static const u32 test_srv_crt_rsa_len
tls_ctx_t * openssl_ctx_get(u32 ctx_index)
#define SESSION_INVALID_HANDLE
int tls_add_vpp_q_tx_evt(session_t *s)
static u32 openssl_ctx_alloc(void)
static void openssl_listen_ctx_free(openssl_listen_ctx_t *lctx)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static int openssl_write_from_fifo_into_ssl(svm_fifo_t *f, SSL *ssl, u32 max_len)
clib_error_t * tls_openssl_api_init(vlib_main_t *vm)
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
#define uword_to_pointer(u, type)
transport_snd_flags_t flags
#define clib_warning(format, args...)
app_cert_key_pair_t * app_cert_key_pair_get_if_valid(u32 index)
int tls_init_ca_chain(void)
void tls_register_engine(const tls_engine_vft_t *vft, crypto_engine_type_t type)
int openssl_resume_handler(tls_ctx_t *ctx, session_t *tls_session)
static vlib_thread_main_t * vlib_get_thread_main()
tls_ctx_t * openssl_ctx_get_w_thread(u32 ctx_index, u8 thread_index)
static u32 svm_fifo_max_dequeue_cons(svm_fifo_t *f)
Fifo max bytes to dequeue optimized for consumer.
static void svm_fifo_add_want_deq_ntf(svm_fifo_t *f, u8 ntf_type)
Set specific want notification flag.
static int openssl_app_close(tls_ctx_t *ctx)
volatile u8 session_state
State in session layer state machine.
static void * clib_mem_alloc(uword size)
static int openssl_ctx_read_tls(tls_ctx_t *ctx, session_t *tls_session)
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
static void transport_connection_deschedule(transport_connection_t *tc)
vl_api_wireguard_peer_flags_t flags