From a5a9efd4d1995ef6d46dfab4e5b8aba9c5d114ef Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Tue, 5 Jan 2021 17:03:29 -0800 Subject: [PATCH] vcl session: switch to generic cert key apis Remove the deprecated tls apis. Type: improvement Signed-off-by: Florin Coras Change-Id: Ia1e12bd813671146f0aca22e83d04c23ac13e595 --- src/plugins/hs_apps/echo_client.c | 33 ++++---- src/plugins/hs_apps/echo_client.h | 1 + src/plugins/hs_apps/echo_server.c | 36 ++++----- src/plugins/hs_apps/http_server.c | 40 +++++---- src/plugins/hs_apps/vcl/vcl_test_client.c | 28 ++++++- src/plugins/hs_apps/vcl/vcl_test_server.c | 20 ++++- src/plugins/http_static/http_static.h | 3 + src/plugins/http_static/static_server.c | 37 +++++---- src/vcl/ldp.c | 105 +++++++++++++----------- src/vcl/vcl_bapi.c | 130 +++++++++++++----------------- src/vcl/vcl_private.h | 19 +++-- src/vcl/vppcom.c | 39 ++++++++- src/vcl/vppcom.h | 15 +++- src/vnet/session/application.c | 28 ++----- src/vnet/session/application_interface.h | 4 +- src/vnet/session/session.api | 4 +- src/vnet/session/session_api.c | 79 +----------------- 17 files changed, 310 insertions(+), 311 deletions(-) diff --git a/src/plugins/hs_apps/echo_client.c b/src/plugins/hs_apps/echo_client.c index 50d815748a5..c26329468ec 100644 --- a/src/plugins/hs_apps/echo_client.c +++ b/src/plugins/hs_apps/echo_client.c @@ -620,8 +620,7 @@ static session_cb_vft_t echo_clients = { static clib_error_t * echo_clients_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret) { - vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert; - vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key; + vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair; u32 prealloc_fifos, segment_size = 256 << 20; echo_client_main_t *ecm = &echo_client_main; vnet_app_attach_args_t _a, *a = &_a; @@ -667,17 +666,14 @@ echo_clients_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret) ecm->app_index = a->app_index; vec_free (a->name); - clib_memset (a_cert, 0, sizeof (*a_cert)); - a_cert->app_index = a->app_index; - vec_validate (a_cert->cert, test_srv_crt_rsa_len); - clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len); - vnet_app_add_tls_cert (a_cert); - - clib_memset (a_key, 0, sizeof (*a_key)); - a_key->app_index = a->app_index; - vec_validate (a_key->key, test_srv_key_rsa_len); - clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len); - vnet_app_add_tls_key (a_key); + clib_memset (ck_pair, 0, sizeof (*ck_pair)); + ck_pair->cert = (u8 *) test_srv_crt_rsa; + ck_pair->key = (u8 *) test_srv_key_rsa; + ck_pair->cert_len = test_srv_crt_rsa_len; + ck_pair->key_len = test_srv_key_rsa_len; + vnet_app_add_cert_key_pair (ck_pair); + ecm->ckpair_index = ck_pair->index; + return 0; } @@ -693,6 +689,8 @@ echo_clients_detach () rv = vnet_application_detach (da); ecm->test_client_attached = 0; ecm->app_index = ~0; + vnet_app_del_cert_key_pair (ecm->ckpair_index); + return rv; } @@ -723,20 +721,25 @@ echo_clients_start_tx_pthread (echo_client_main_t * ecm) clib_error_t * echo_clients_connect (vlib_main_t * vm, u32 n_clients) { + session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL; echo_client_main_t *ecm = &echo_client_main; vnet_connect_args_t _a, *a = &_a; int i, rv; clib_memset (a, 0, sizeof (*a)); + if (parse_uri ((char *) ecm->connect_uri, &sep)) + return clib_error_return (0, "invalid uri"); + for (i = 0; i < n_clients; i++) { - a->uri = (char *) ecm->connect_uri; + clib_memcpy (&a->sep_ext, &sep, sizeof (sep)); a->api_context = i; a->app_index = ecm->app_index; + a->sep_ext.ckpair_index = ecm->ckpair_index; vlib_worker_thread_barrier_sync (vm); - if ((rv = vnet_connect_uri (a))) + if ((rv = vnet_connect (a))) { vlib_worker_thread_barrier_release (vm); return clib_error_return (0, "connect returned: %d", rv); diff --git a/src/plugins/hs_apps/echo_client.h b/src/plugins/hs_apps/echo_client.h index 34cf0bd4764..c4983ca78d8 100644 --- a/src/plugins/hs_apps/echo_client.h +++ b/src/plugins/hs_apps/echo_client.h @@ -66,6 +66,7 @@ typedef struct u8 is_dgram; u32 no_copy; /**< Don't memcpy data to tx fifo */ u32 quic_streams; /**< QUIC streams per connection */ + u32 ckpair_index; /**< Cert key pair for tls/quic */ /* * Test state variables diff --git a/src/plugins/hs_apps/echo_server.c b/src/plugins/hs_apps/echo_server.c index a5335bb2f20..1c4022537ba 100644 --- a/src/plugins/hs_apps/echo_server.c +++ b/src/plugins/hs_apps/echo_server.c @@ -47,7 +47,9 @@ typedef struct u32 private_segment_size; /**< Size of private segments */ char *server_uri; /**< Server URI */ u32 tls_engine; /**< TLS engine: mbedtls/openssl */ + u32 ckpair_index; /**< Cert and key for tls/quic */ u8 is_dgram; /**< set if transport is dgram */ + /* * Test state */ @@ -304,8 +306,7 @@ static session_cb_vft_t echo_server_session_cb_vft = { static int echo_server_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret) { - vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert; - vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key; + vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair; echo_server_main_t *esm = &echo_server_main; vnet_app_attach_args_t _a, *a = &_a; u64 options[APP_OPTIONS_N_OPTIONS]; @@ -357,17 +358,14 @@ echo_server_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret) esm->app_index = a->app_index; vec_free (a->name); - clib_memset (a_cert, 0, sizeof (*a_cert)); - a_cert->app_index = a->app_index; - vec_validate (a_cert->cert, test_srv_crt_rsa_len); - clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len); - vnet_app_add_tls_cert (a_cert); - - clib_memset (a_key, 0, sizeof (*a_key)); - a_key->app_index = a->app_index; - vec_validate (a_key->key, test_srv_key_rsa_len); - clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len); - vnet_app_add_tls_key (a_key); + clib_memset (ck_pair, 0, sizeof (*ck_pair)); + ck_pair->cert = (u8 *) test_srv_crt_rsa; + ck_pair->key = (u8 *) test_srv_key_rsa; + ck_pair->cert_len = test_srv_crt_rsa_len; + ck_pair->key_len = test_srv_key_rsa_len; + vnet_app_add_cert_key_pair (ck_pair); + esm->ckpair_index = ck_pair->index; + return 0; } @@ -381,6 +379,7 @@ echo_server_detach (void) da->app_index = esm->app_index; rv = vnet_application_detach (da); esm->app_index = ~0; + vnet_app_del_cert_key_pair (esm->ckpair_index); return rv; } @@ -389,17 +388,16 @@ echo_server_listen () { i32 rv; echo_server_main_t *esm = &echo_server_main; - vnet_listen_args_t _args = { - .app_index = esm->app_index, - .sep_ext = { - .app_wrk_index = 0, - } - }, *args = &_args; + vnet_listen_args_t _args = { 0 }, *args = &_args; + + args->sep_ext.app_wrk_index = 0; if ((rv = parse_uri (esm->server_uri, &args->sep_ext))) { return -1; } + args->app_index = esm->app_index; + args->sep_ext.ckpair_index = esm->ckpair_index; if (args->sep_ext.transport_proto == TRANSPORT_PROTO_UDP) { diff --git a/src/plugins/hs_apps/http_server.c b/src/plugins/hs_apps/http_server.c index ce4e09addbc..e1674d5d2f1 100644 --- a/src/plugins/hs_apps/http_server.c +++ b/src/plugins/hs_apps/http_server.c @@ -73,6 +73,9 @@ typedef struct /* process node index for evnt scheduling */ u32 node_index; + /* Cert key pair for tls */ + u32 ckpair_index; + tw_timer_wheel_2t_1w_2048sl_t tw; clib_spinlock_t tw_lock; @@ -712,8 +715,7 @@ static session_cb_vft_t http_server_session_cb_vft = { static int http_server_attach () { - vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert; - vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key; + vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair; http_server_main_t *hsm = &http_server_main; u64 options[APP_OPTIONS_N_OPTIONS]; vnet_app_attach_args_t _a, *a = &_a; @@ -746,17 +748,13 @@ http_server_attach () vec_free (a->name); hsm->app_index = a->app_index; - clib_memset (a_cert, 0, sizeof (*a_cert)); - a_cert->app_index = a->app_index; - vec_validate (a_cert->cert, test_srv_crt_rsa_len); - clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len); - vnet_app_add_tls_cert (a_cert); - - clib_memset (a_key, 0, sizeof (*a_key)); - a_key->app_index = a->app_index; - vec_validate (a_key->key, test_srv_key_rsa_len); - clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len); - vnet_app_add_tls_key (a_key); + clib_memset (ck_pair, 0, sizeof (*ck_pair)); + ck_pair->cert = (u8 *) test_srv_crt_rsa; + ck_pair->key = (u8 *) test_srv_key_rsa; + ck_pair->cert_len = test_srv_crt_rsa_len; + ck_pair->key_len = test_srv_key_rsa_len; + vnet_app_add_cert_key_pair (ck_pair); + hsm->ckpair_index = ck_pair->index; return 0; } @@ -764,14 +762,24 @@ http_server_attach () static int http_server_listen () { + session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL; http_server_main_t *hsm = &http_server_main; vnet_listen_args_t _a, *a = &_a; + char *uri = "tcp://0.0.0.0/80"; + clib_memset (a, 0, sizeof (*a)); a->app_index = hsm->app_index; - a->uri = "tcp://0.0.0.0/80"; + if (hsm->uri) - a->uri = (char *) hsm->uri; - return vnet_bind_uri (a); + uri = (char *) hsm->uri; + + if (parse_uri (uri, &sep)) + return -1; + + clib_memcpy (&a->sep_ext, &sep, sizeof (sep)); + a->sep_ext.ckpair_index = hsm->ckpair_index; + + return vnet_listen (a); } static void diff --git a/src/plugins/hs_apps/vcl/vcl_test_client.c b/src/plugins/hs_apps/vcl/vcl_test_client.c index 51544a7a445..0aff98ef1dd 100644 --- a/src/plugins/hs_apps/vcl/vcl_test_client.c +++ b/src/plugins/hs_apps/vcl/vcl_test_client.c @@ -51,6 +51,7 @@ typedef struct vcl_test_t post_test; uint8_t proto; uint32_t n_workers; + uint32_t ckpair_index; volatile int active_workers; struct sockaddr_storage server_addr; } vcl_test_client_main_t; @@ -265,6 +266,13 @@ vtc_connect_test_sessions (vcl_test_client_worker_t * wrk) return ts->fd; } + if (vcm->proto == VPPCOM_PROTO_TLS) + { + uint32_t ckp_len = sizeof (vcm->ckpair_index); + vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_CKPAIR, + &vcm->ckpair_index, &ckp_len); + } + /* Connect is blocking */ rv = vppcom_session_connect (ts->fd, &vcm->server_endpt); if (rv < 0) @@ -1099,11 +1107,23 @@ main (int argc, char **argv) if (vcm->proto == VPPCOM_PROTO_TLS || vcm->proto == VPPCOM_PROTO_QUIC) { + vppcom_cert_key_pair_t ckpair; + uint32_t ckp_len; + int ckp_index; + vtinf ("Adding tls certs ..."); - vppcom_session_tls_add_cert (ctrl->fd, vcl_test_crt_rsa, - vcl_test_crt_rsa_len); - vppcom_session_tls_add_key (ctrl->fd, vcl_test_key_rsa, - vcl_test_key_rsa_len); + ckpair.cert = vcl_test_crt_rsa; + ckpair.key = vcl_test_key_rsa; + ckpair.cert_len = vcl_test_crt_rsa_len; + ckpair.key_len = vcl_test_key_rsa_len; + ckp_index = vppcom_add_cert_key_pair (&ckpair); + if (ckp_index < 0) + vtfail ("vppcom_add_cert_key_pair()", ckp_index); + + vcm->ckpair_index = ckp_index; + ckp_len = sizeof (ckp_index); + vppcom_session_attr (ctrl->fd, VPPCOM_ATTR_SET_CKPAIR, &ckp_index, + &ckp_len); } vtinf ("Connecting to server..."); diff --git a/src/plugins/hs_apps/vcl/vcl_test_server.c b/src/plugins/hs_apps/vcl/vcl_test_server.c index 798fd72b481..a2a4d6ac3b0 100644 --- a/src/plugins/hs_apps/vcl/vcl_test_server.c +++ b/src/plugins/hs_apps/vcl/vcl_test_server.c @@ -553,10 +553,22 @@ vts_worker_init (vcl_test_server_worker_t * wrk) if (vsm->cfg.proto == VPPCOM_PROTO_TLS || vsm->cfg.proto == VPPCOM_PROTO_QUIC) { - vppcom_session_tls_add_cert (wrk->listen_fd, vcl_test_crt_rsa, - vcl_test_crt_rsa_len); - vppcom_session_tls_add_key (wrk->listen_fd, vcl_test_key_rsa, - vcl_test_key_rsa_len); + vppcom_cert_key_pair_t ckpair; + uint32_t ckp_len; + int ckp_index; + + vtinf ("Adding tls certs ..."); + ckpair.cert = vcl_test_crt_rsa; + ckpair.key = vcl_test_key_rsa; + ckpair.cert_len = vcl_test_crt_rsa_len; + ckpair.key_len = vcl_test_key_rsa_len; + ckp_index = vppcom_add_cert_key_pair (&ckpair); + if (ckp_index < 0) + vtfail ("vppcom_add_cert_key_pair()", ckp_index); + + ckp_len = sizeof (ckp_index); + vppcom_session_attr (wrk->listen_fd, VPPCOM_ATTR_SET_CKPAIR, &ckp_index, + &ckp_len); } rv = vppcom_session_bind (wrk->listen_fd, &vsm->cfg.endpt); diff --git a/src/plugins/http_static/http_static.h b/src/plugins/http_static/http_static.h index daa2ecf9e89..8ee0f92cd44 100644 --- a/src/plugins/http_static/http_static.h +++ b/src/plugins/http_static/http_static.h @@ -181,6 +181,9 @@ typedef struct /** Process node index for event scheduling */ u32 node_index; + /** Cert and key pair for tls */ + u32 ckpair_index; + /** Session cleanup timer wheel */ tw_timer_wheel_2t_1w_2048sl_t tw; clib_spinlock_t tw_lock; diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c index 0ae67412016..b354666f816 100644 --- a/src/plugins/http_static/static_server.c +++ b/src/plugins/http_static/static_server.c @@ -1140,8 +1140,7 @@ static session_cb_vft_t http_static_server_session_cb_vft = { static int http_static_server_attach () { - vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert; - vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key; + vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair; http_static_server_main_t *hsm = &http_static_server_main; u64 options[APP_OPTIONS_N_OPTIONS]; vnet_app_attach_args_t _a, *a = &_a; @@ -1175,17 +1174,13 @@ http_static_server_attach () vec_free (a->name); hsm->app_index = a->app_index; - clib_memset (a_cert, 0, sizeof (*a_cert)); - a_cert->app_index = a->app_index; - vec_validate (a_cert->cert, test_srv_crt_rsa_len); - clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len); - vnet_app_add_tls_cert (a_cert); - - clib_memset (a_key, 0, sizeof (*a_key)); - a_key->app_index = a->app_index; - vec_validate (a_key->key, test_srv_key_rsa_len); - clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len); - vnet_app_add_tls_key (a_key); + clib_memset (ck_pair, 0, sizeof (*ck_pair)); + ck_pair->cert = (u8 *) test_srv_crt_rsa; + ck_pair->key = (u8 *) test_srv_key_rsa; + ck_pair->cert_len = test_srv_crt_rsa_len; + ck_pair->key_len = test_srv_key_rsa_len; + vnet_app_add_cert_key_pair (ck_pair); + hsm->ckpair_index = ck_pair->index; return 0; } @@ -1194,13 +1189,23 @@ static int http_static_server_listen () { http_static_server_main_t *hsm = &http_static_server_main; + session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL; vnet_listen_args_t _a, *a = &_a; + char *uri = "tcp://0.0.0.0/80"; + clib_memset (a, 0, sizeof (*a)); a->app_index = hsm->app_index; - a->uri = "tcp://0.0.0.0/80"; + if (hsm->uri) - a->uri = (char *) hsm->uri; - return vnet_bind_uri (a); + uri = (char *) hsm->uri; + + if (parse_uri (uri, &sep)) + return -1; + + clib_memcpy (&a->sep_ext, &sep, sizeof (sep)); + a->sep_ext.ckpair_index = hsm->ckpair_index; + + return vnet_listen (a); } static void diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c index 98ed4a9b1ab..b72c0c54acd 100644 --- a/src/vcl/ldp.c +++ b/src/vcl/ldp.c @@ -100,10 +100,15 @@ typedef struct u32 vlsh_bit_val; u32 vlsh_bit_mask; u32 debug; - u8 transparent_tls; /** vcl needs next epoll_create to go to libc_epoll */ u8 vcl_needs_real_epoll; + + /** + * crypto state used only for testing + */ + u8 transparent_tls; + u32 ckpair_index; } ldp_main_t; #define LDP_DEBUG ldp->debug @@ -121,6 +126,7 @@ static ldp_main_t ldp_main = { .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1, .debug = LDP_DEBUG_INIT, .transparent_tls = 0, + .ckpair_index = ~0, }; static ldp_main_t *ldp = &ldp_main; @@ -902,68 +908,71 @@ pselect (int nfds, fd_set * __restrict readfds, /* If transparent TLS mode is turned on, then ldp will load key and cert. */ static int -load_tls_cert (vls_handle_t vlsh) +load_cert_key_pair (void) { - char *env_var_str = getenv (LDP_ENV_TLS_CERT); - char inbuf[4096]; - char *tls_cert; - int cert_size; + char *cert_str = getenv (LDP_ENV_TLS_CERT); + char *key_str = getenv (LDP_ENV_TLS_KEY); + char cert_buf[4096], key_buf[4096]; + int cert_size, key_size; + vppcom_cert_key_pair_t crypto; + int ckp_index; FILE *fp; - if (env_var_str) - { - fp = fopen (env_var_str, "r"); - if (fp == NULL) - { - LDBG (0, "ERROR: failed to open cert file %s \n", env_var_str); - return -1; - } - cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp); - tls_cert = inbuf; - vppcom_session_tls_add_cert (vlsh_to_session_index (vlsh), tls_cert, - cert_size); - fclose (fp); - } - else + if (!cert_str || !key_str) { LDBG (0, "ERROR: failed to read LDP environment %s\n", LDP_ENV_TLS_CERT); return -1; } - return 0; -} -static int -load_tls_key (vls_handle_t vlsh) -{ - char *env_var_str = getenv (LDP_ENV_TLS_KEY); - char inbuf[4096]; - char *tls_key; - int key_size; - FILE *fp; + fp = fopen (cert_str, "r"); + if (fp == NULL) + { + LDBG (0, "ERROR: failed to open cert file %s \n", cert_str); + return -1; + } + cert_size = fread (cert_buf, sizeof (char), sizeof (cert_buf), fp); + fclose (fp); - if (env_var_str) + fp = fopen (key_str, "r"); + if (fp == NULL) { - fp = fopen (env_var_str, "r"); - if (fp == NULL) - { - LDBG (0, "ERROR: failed to open key file %s \n", env_var_str); - return -1; - } - key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp); - tls_key = inbuf; - vppcom_session_tls_add_key (vlsh_to_session_index (vlsh), tls_key, - key_size); - fclose (fp); + LDBG (0, "ERROR: failed to open key file %s \n", key_str); + return -1; } - else + key_size = fread (key_buf, sizeof (char), sizeof (key_buf), fp); + fclose (fp); + + crypto.cert = cert_buf; + crypto.key = key_buf; + crypto.cert_len = cert_size; + crypto.key_len = key_size; + ckp_index = vppcom_add_cert_key_pair (&crypto); + if (ckp_index < 0) { - LDBG (0, "ERROR: failed to read LDP environment %s\n", LDP_ENV_TLS_KEY); + LDBG (0, "ERROR: failed to add cert key pair\n"); return -1; } + + ldp->ckpair_index = ckp_index; + return 0; } +static int +assign_cert_key_pair (vls_handle_t vlsh) +{ + uint32_t ckp_len; + + if (ldp->ckpair_index == ~0 && load_cert_key_pair () < 0) + return -1; + + ckp_len = sizeof (ldp->ckpair_index); + return vppcom_session_attr (vlsh_to_session_index (vlsh), + VPPCOM_ATTR_SET_CKPAIR, &ldp->ckpair_index, + &ckp_len); +} + int socket (int domain, int type, int protocol) { @@ -999,10 +1008,8 @@ socket (int domain, int type, int protocol) { if (ldp->transparent_tls) { - if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0) - { - return -1; - } + if (assign_cert_key_pair (vlsh) < 0) + return -1; } rv = ldp_vlsh_to_fd (vlsh); } diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c index 8e24bfeee0c..7d241624d01 100644 --- a/src/vcl/vcl_bapi.c +++ b/src/vcl/vcl_bapi.c @@ -244,41 +244,39 @@ failed: } static void - vl_api_application_tls_cert_add_reply_t_handler - (vl_api_application_tls_cert_add_reply_t * mp) +vl_api_app_add_cert_key_pair_reply_t_handler ( + vl_api_app_add_cert_key_pair_reply_t *mp) { vcl_worker_t *wrk = vcl_worker_get_current (); if (mp->retval) { - VDBG (0, "add cert failed: %U", format_api_error, ntohl (mp->retval)); - wrk->bapi_app_state = STATE_APP_FAILED; + VDBG (0, "Adding cert and key failed: %U", format_api_error, + ntohl (mp->retval)); return; } + wrk->bapi_return = clib_net_to_host_u32 (mp->index); wrk->bapi_app_state = STATE_APP_READY; } static void - vl_api_application_tls_key_add_reply_t_handler - (vl_api_application_tls_key_add_reply_t * mp) +vl_api_app_del_cert_key_pair_reply_t_handler ( + vl_api_app_del_cert_key_pair_reply_t *mp) { - vcl_worker_t *wrk = vcl_worker_get_current (); - if (mp->retval) { - VDBG (0, "add key failed: %U", format_api_error, ntohl (mp->retval)); - wrk->bapi_app_state = STATE_APP_FAILED; + VDBG (0, "Deleting cert and key failed: %U", format_api_error, + ntohl (mp->retval)); return; } - wrk->bapi_app_state = STATE_APP_READY; } -#define foreach_sock_msg \ -_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \ -_(APP_ATTACH_REPLY, app_attach_reply) \ -_(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply) \ -_(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply) \ -_(APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply) \ +#define foreach_sock_msg \ + _ (SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \ + _ (APP_ATTACH_REPLY, app_attach_reply) \ + _ (APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply) \ + _ (APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply) \ + _ (APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply) static void vcl_bapi_hookup (void) @@ -408,38 +406,41 @@ vcl_bapi_send_child_worker_del (vcl_worker_t * child_wrk) vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp); } -void -vcl_bapi_send_application_tls_cert_add (vcl_session_t * session, char *cert, - u32 cert_len) +static void +vcl_bapi_send_app_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair) { vcl_worker_t *wrk = vcl_worker_get_current (); - vl_api_application_tls_cert_add_t *cert_mp; - - cert_mp = vl_msg_api_alloc (sizeof (*cert_mp) + cert_len); - clib_memset (cert_mp, 0, sizeof (*cert_mp)); - cert_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_CERT_ADD); - cert_mp->client_index = wrk->api_client_handle; - cert_mp->context = session->session_index; - cert_mp->cert_len = clib_host_to_net_u16 (cert_len); - clib_memcpy_fast (cert_mp->cert, cert, cert_len); - vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & cert_mp); + u32 cert_len = test_srv_crt_rsa_len; + u32 key_len = test_srv_key_rsa_len; + vl_api_app_add_cert_key_pair_t *bmp; + + bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len); + clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len); + + bmp->_vl_msg_id = ntohs (VL_API_APP_ADD_CERT_KEY_PAIR); + bmp->client_index = wrk->api_client_handle; + bmp->context = wrk->wrk_index; + bmp->cert_len = clib_host_to_net_u16 (cert_len); + bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len); + clib_memcpy_fast (bmp->certkey, test_srv_crt_rsa, cert_len); + clib_memcpy_fast (bmp->certkey + cert_len, test_srv_key_rsa, key_len); + + vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp); } -void -vcl_bapi_send_application_tls_key_add (vcl_session_t * session, char *key, - u32 key_len) +static void +vcl_bapi_send_app_del_cert_key_pair (u32 ckpair_index) { vcl_worker_t *wrk = vcl_worker_get_current (); - vl_api_application_tls_key_add_t *key_mp; - - key_mp = vl_msg_api_alloc (sizeof (*key_mp) + key_len); - clib_memset (key_mp, 0, sizeof (*key_mp)); - key_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_KEY_ADD); - key_mp->client_index = wrk->api_client_handle; - key_mp->context = session->session_index; - key_mp->key_len = clib_host_to_net_u16 (key_len); - clib_memcpy_fast (key_mp->key, key, key_len); - vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & key_mp); + vl_api_app_del_cert_key_pair_t *bmp; + bmp = vl_msg_api_alloc (sizeof (*bmp)); + clib_memset (bmp, 0, sizeof (*bmp)); + + bmp->_vl_msg_id = ntohs (VL_API_APP_DEL_CERT_KEY_PAIR); + bmp->client_index = wrk->api_client_handle; + bmp->context = wrk->wrk_index; + bmp->index = clib_host_to_net_u32 (ckpair_index); + vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp); } u32 @@ -706,48 +707,27 @@ vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds) } int -vppcom_session_tls_add_cert (uint32_t session_handle, char *cert, - uint32_t cert_len) +vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair) { - vcl_worker_t *wrk = vcl_worker_get_current (); - vcl_session_t *session = 0; - session = vcl_session_get_w_handle (wrk, session_handle); - if (!session) - return VPPCOM_EBADFD; + if (ckpair->key_len == 0 || ckpair->key_len == ~0) + return VPPCOM_EINVAL; - if (cert_len == 0 || cert_len == ~0) - return VPPCOM_EBADFD; - - /* - * Send listen request to vpp and wait for reply - */ - vcl_bapi_send_application_tls_cert_add (session, cert, cert_len); + vcl_bapi_send_app_add_cert_key_pair (ckpair); wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA; vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY); - return VPPCOM_OK; + if (wrk->bapi_app_state == STATE_APP_READY) + return wrk->bapi_return; + return VPPCOM_EFAULT; } int -vppcom_session_tls_add_key (uint32_t session_handle, char *key, - uint32_t key_len) +vcl_bapi_del_cert_key_pair (u32 ckpair_index) { - - vcl_worker_t *wrk = vcl_worker_get_current (); - vcl_session_t *session = 0; - - session = vcl_session_get_w_handle (wrk, session_handle); - if (!session) - return VPPCOM_EBADFD; - - if (key_len == 0 || key_len == ~0) - return VPPCOM_EBADFD; - - vcl_bapi_send_application_tls_key_add (session, key, key_len); - wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA; - vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY); - return VPPCOM_OK; + /* Don't wait for reply */ + vcl_bapi_send_app_del_cert_key_pair (ckpair_index); + return 0; } int diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 0aa2fc10fa0..7104adc4452 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -154,12 +154,13 @@ typedef struct vcl_session_ vcl_session_msg_t *accept_evts_fifo; u64 vpp_handle; + u64 parent_handle; u32 listener_index; /**< index of parent listener (if any) */ int n_accepted_sessions; /**< sessions accepted by this listener */ + vppcom_epoll_t vep; u32 attributes; /**< see @ref vppcom_session_attr_t */ - u64 parent_handle; int libc_epfd; - vppcom_epoll_t vep; + u32 ckpair_index; u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF) u32 rcvbuf_size; // VPP-TBD: Hack until support setsockopt(SO_RCVBUF) @@ -287,6 +288,7 @@ typedef struct vcl_worker_ /* State of the connection, shared between msg RX thread and main thread */ volatile vcl_bapi_app_state_t bapi_app_state; + volatile uword bapi_return; /** vcl needs next epoll_create to go to libc_epoll */ u8 vcl_needs_real_epoll; @@ -535,6 +537,13 @@ vcl_session_is_cl (vcl_session_t * s) return 0; } +static inline u8 +vcl_session_has_crypto (vcl_session_t *s) +{ + return (s->session_type == VPPCOM_PROTO_TLS || + s->session_type == VPPCOM_PROTO_QUIC); +} + static inline u8 vcl_session_is_ready (vcl_session_t * s) { @@ -699,10 +708,8 @@ int vcl_bapi_app_worker_add (void); void vcl_bapi_app_worker_del (vcl_worker_t * wrk); void vcl_bapi_disconnect_from_vpp (void); int vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds); -void vcl_bapi_send_application_tls_cert_add (vcl_session_t * session, - char *cert, u32 cert_len); -void vcl_bapi_send_application_tls_key_add (vcl_session_t * session, - char *key, u32 key_len); +int vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair); +int vcl_bapi_del_cert_key_pair (u32 ckpair_index); u32 vcl_bapi_max_nsid_len (void); int vcl_bapi_worker_set (void); diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index dbb2cd59a3b..412b6a4b995 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -182,6 +182,7 @@ vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s) clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip)); mp->port = s->transport.lcl_port; mp->proto = s->session_type; + mp->ckpair_index = s->ckpair_index; if (s->flags & VCL_SESSION_F_CONNECTED) mp->flags = TRANSPORT_CFG_F_CONNECTED; app_send_ctrl_evt_to_vpp (mq, app_evt); @@ -208,6 +209,7 @@ vcl_send_session_connect (vcl_worker_t * wrk, vcl_session_t * s) mp->port = s->transport.rmt_port; mp->lcl_port = s->transport.lcl_port; mp->proto = s->session_type; + mp->ckpair_index = s->ckpair_index; if (s->flags & VCL_SESSION_F_CONNECTED) mp->flags |= TRANSPORT_CFG_F_CONNECTED; app_send_ctrl_evt_to_vpp (mq, app_evt); @@ -1282,6 +1284,7 @@ vppcom_session_create (u8 proto, u8 is_nonblocking) session->session_type = proto; session->session_state = VCL_STATE_CLOSED; session->vpp_handle = ~0; + session->ckpair_index = ~0; session->is_dgram = vcl_proto_is_dgram (proto); if (is_nonblocking) @@ -3082,10 +3085,10 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, void *buffer, uint32_t * buflen) { vcl_worker_t *wrk = vcl_worker_get_current (); - vcl_session_t *session; - int rv = VPPCOM_OK; u32 *flags = buffer, tmp_flags = 0; vppcom_endpt_t *ep = buffer; + vcl_session_t *session; + int rv = VPPCOM_OK; session = vcl_session_get_w_handle (wrk, session_handle); if (!session) @@ -3633,6 +3636,16 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, session->flags |= VCL_SESSION_F_CONNECTED; break; + case VPPCOM_ATTR_SET_CKPAIR: + if (!(buffer && buflen && (*buflen == sizeof (int))) || + !vcl_session_has_crypto (session)) + { + rv = VPPCOM_EINVAL; + break; + } + session->ckpair_index = *(uint32_t *) buffer; + break; + default: rv = VPPCOM_EINVAL; break; @@ -4012,6 +4025,28 @@ vppcom_retval_str (int retval) return st; } +int +vppcom_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair) +{ + if (vcm->cfg.vpp_app_socket_api) + { + clib_warning ("not supported"); + return VPPCOM_EINVAL; + } + return vcl_bapi_add_cert_key_pair (ckpair); +} + +int +vppcom_del_cert_key_pair (uint32_t ckpair_index) +{ + if (vcm->cfg.vpp_app_socket_api) + { + clib_warning ("not supported"); + return VPPCOM_EINVAL; + } + return vcl_bapi_del_cert_key_pair (ckpair_index); +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h index 09303008870..77be8061159 100644 --- a/src/vcl/vppcom.h +++ b/src/vcl/vppcom.h @@ -71,6 +71,14 @@ typedef struct vppcom_endpt_t_ typedef uint32_t vcl_session_handle_t; +typedef struct vppcom_cert_key_pair_ +{ + char *cert; + char *key; + uint32_t cert_len; + uint32_t key_len; +} vppcom_cert_key_pair_t; + typedef enum { VPPCOM_OK = 0, @@ -129,6 +137,7 @@ typedef enum VPPCOM_ATTR_SET_SHUT, VPPCOM_ATTR_GET_SHUT, VPPCOM_ATTR_SET_CONNECTED, + VPPCOM_ATTR_SET_CKPAIR, } vppcom_attr_op_t; typedef struct _vcl_poll @@ -204,10 +213,8 @@ extern int vppcom_session_read_segments (uint32_t session_handle, uint32_t max_bytes); extern void vppcom_session_free_segments (uint32_t session_handle, uint32_t n_bytes); -extern int vppcom_session_tls_add_cert (uint32_t session_handle, char *cert, - uint32_t cert_len); -extern int vppcom_session_tls_add_key (uint32_t session_handle, char *key, - uint32_t key_len); +extern int vppcom_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair); +extern int vppcom_del_cert_key_pair (uint32_t ckpair_index); extern int vppcom_unformat_proto (uint8_t * proto, char *proto_str); extern int vppcom_session_is_connectable_listener (uint32_t session_handle); extern int vppcom_session_listener (uint32_t session_handle); diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 20b0a9e137b..906a73e9d79 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -1320,26 +1320,6 @@ application_get_segment_manager_properties (u32 app_index) return &app->sm_properties; } -clib_error_t * -vnet_app_add_tls_cert (vnet_app_add_tls_cert_args_t * a) -{ - /* Deprected, will be remove after 20.01 */ - app_cert_key_pair_t *ckpair; - ckpair = app_cert_key_pair_get_default (); - ckpair->cert = vec_dup (a->cert); - return 0; -} - -clib_error_t * -vnet_app_add_tls_key (vnet_app_add_tls_key_args_t * a) -{ - /* Deprected, will be remove after 20.01 */ - app_cert_key_pair_t *ckpair; - ckpair = app_cert_key_pair_get_default (); - ckpair->key = vec_dup (a->key); - return 0; -} - static void application_format_listeners (application_t * app, int verbose) { @@ -1706,8 +1686,10 @@ int vnet_app_add_cert_key_pair (vnet_app_add_cert_key_pair_args_t * a) { app_cert_key_pair_t *ckpair = app_cert_key_pair_alloc (); - ckpair->cert = vec_dup (a->cert); - ckpair->key = vec_dup (a->key); + vec_validate (ckpair->cert, a->cert_len - 1); + clib_memcpy_fast (ckpair->cert, a->cert, a->cert_len); + vec_validate (ckpair->key, a->key_len - 1); + clib_memcpy_fast (ckpair->key, a->key, a->key_len); a->index = ckpair->cert_key_index; return 0; } @@ -1749,7 +1731,7 @@ vnet_app_del_cert_key_pair (u32 index) clib_error_t * application_init (vlib_main_t * vm) { - /* Add a certificate with index 0 to support legacy apis */ + /* Index 0 was originally used by legacy apis, maintain as invalid */ (void) app_cert_key_pair_alloc (); app_main.last_crypto_engine = CRYPTO_ENGINE_LAST; app_main.app_by_name = hash_create_vec (0, sizeof (u8), sizeof (uword)); diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index 96142573b98..b2e0ef9da84 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -178,6 +178,8 @@ typedef struct _vnet_app_add_cert_key_pair_args_ { u8 *cert; u8 *key; + u32 cert_len; + u32 key_len; u32 index; } vnet_app_add_cert_key_pair_args_t; @@ -271,8 +273,6 @@ int vnet_connect (vnet_connect_args_t * a); int vnet_unlisten (vnet_unlisten_args_t * a); int vnet_disconnect_session (vnet_disconnect_args_t * a); -clib_error_t *vnet_app_add_tls_cert (vnet_app_add_tls_cert_args_t * a); -clib_error_t *vnet_app_add_tls_key (vnet_app_add_tls_key_args_t * a); int vnet_app_add_cert_key_pair (vnet_app_add_cert_key_pair_args_t * a); int vnet_app_del_cert_key_pair (u32 index); /** Ask for app cb on pair deletion */ diff --git a/src/vnet/session/session.api b/src/vnet/session/session.api index 091b876faee..53e2834e839 100644 --- a/src/vnet/session/session.api +++ b/src/vnet/session/session.api @@ -13,7 +13,7 @@ * limitations under the License. */ -option version = "3.2.0"; +option version = "4.0.0"; import "vnet/interface_types.api"; import "vnet/ip/ip_types.api"; @@ -125,6 +125,7 @@ autoreply define app_del_cert_key_pair { @param cert - certificate as a string */ autoreply define application_tls_cert_add { + option deprecated="to be removed post 21.06"; u32 client_index; u32 context; u32 app_index; @@ -140,6 +141,7 @@ autoreply define application_tls_cert_add { @param key - PEM encoded key as a string */ autoreply define application_tls_key_add { + option deprecated="to be removed post 21.06"; u32 client_index; u32 context; u32 app_index; diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 2073a15af64..2e215f76051 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -49,8 +49,6 @@ _(SESSION_ENABLE_DISABLE, session_enable_disable) \ _(APP_NAMESPACE_ADD_DEL, app_namespace_add_del) \ _(SESSION_RULE_ADD_DEL, session_rule_add_del) \ _(SESSION_RULES_DUMP, session_rules_dump) \ -_(APPLICATION_TLS_CERT_ADD, application_tls_cert_add) \ -_(APPLICATION_TLS_KEY_ADD, application_tls_key_add) \ _(APP_ADD_CERT_KEY_PAIR, app_add_cert_key_pair) \ _(APP_DEL_CERT_KEY_PAIR, app_del_cert_key_pair) \ _(APP_WORKER_ADD_DEL, app_worker_add_del) \ @@ -1065,13 +1063,11 @@ vl_api_app_add_cert_key_pair_t_handler (vl_api_app_add_cert_key_pair_t * mp) } clib_memset (a, 0, sizeof (*a)); - vec_validate (a->cert, cert_len); - vec_validate (a->key, key_len); - clib_memcpy_fast (a->cert, mp->certkey, cert_len); - clib_memcpy_fast (a->key, mp->certkey + cert_len, key_len); + a->cert = mp->certkey; + a->key = mp->certkey + cert_len; + a->cert_len = cert_len; + a->key_len = key_len; rv = vnet_app_add_cert_key_pair (a); - vec_free (a->cert); - vec_free (a->key); done: /* *INDENT-OFF* */ @@ -1100,73 +1096,6 @@ done: REPLY_MACRO (VL_API_APP_DEL_CERT_KEY_PAIR_REPLY); } -/* ### WILL BE DEPRECATED POST 20.01 ### */ -static void -vl_api_application_tls_cert_add_t_handler (vl_api_application_tls_cert_add_t * - mp) -{ - vl_api_application_tls_cert_add_reply_t *rmp; - app_cert_key_pair_t *ckpair; - application_t *app; - u32 cert_len; - int rv = 0; - if (session_main_is_enabled () == 0) - { - rv = VNET_API_ERROR_FEATURE_DISABLED; - goto done; - } - if (!(app = application_lookup (mp->client_index))) - { - rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED; - goto done; - } - cert_len = clib_net_to_host_u16 (mp->cert_len); - if (cert_len > 10000) - { - rv = VNET_API_ERROR_INVALID_VALUE; - goto done; - } - ckpair = app_cert_key_pair_get_default (); - vec_validate (ckpair->cert, cert_len); - clib_memcpy_fast (ckpair->cert, mp->cert, cert_len); - -done: - REPLY_MACRO (VL_API_APPLICATION_TLS_CERT_ADD_REPLY); -} - -/* ### WILL BE DEPRECATED POST 20.01 ### */ -static void -vl_api_application_tls_key_add_t_handler (vl_api_application_tls_key_add_t * - mp) -{ - vl_api_application_tls_key_add_reply_t *rmp; - app_cert_key_pair_t *ckpair; - application_t *app; - u32 key_len; - int rv = 0; - if (session_main_is_enabled () == 0) - { - rv = VNET_API_ERROR_FEATURE_DISABLED; - goto done; - } - if (!(app = application_lookup (mp->client_index))) - { - rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED; - goto done; - } - key_len = clib_net_to_host_u16 (mp->key_len); - if (key_len > 10000) - { - rv = VNET_API_ERROR_INVALID_VALUE; - goto done; - } - ckpair = app_cert_key_pair_get_default (); - vec_validate (ckpair->key, key_len); - clib_memcpy_fast (ckpair->key, mp->key, key_len); -done: - REPLY_MACRO (VL_API_APPLICATION_TLS_KEY_ADD_REPLY); -} - static clib_error_t * application_reaper_cb (u32 client_index) { -- 2.16.6