From e191d76d248ebbb022533d518b447b7df4efd371 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Wed, 11 Aug 2021 14:55:49 -0700 Subject: [PATCH] session vcl: cert key add/del with socket api Type: improvement Signed-off-by: Florin Coras Change-Id: I70791285cbf427479d2dcbf70ffdce2253add2fb --- src/vcl/vcl_private.h | 2 + src/vcl/vcl_sapi.c | 109 +++++++++++++++++++++++++++++++ src/vcl/vppcom.c | 16 ++--- src/vnet/session/application_interface.h | 20 ++++++ src/vnet/session/session_api.c | 80 +++++++++++++++++++++++ src/vnet/session/session_types.h | 1 + 6 files changed, 218 insertions(+), 10 deletions(-) diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 3233aeca4b2..c9db03cbc2f 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -753,6 +753,8 @@ int vcl_sapi_app_worker_add (void); void vcl_sapi_app_worker_del (vcl_worker_t * wrk); void vcl_sapi_detach (vcl_worker_t * wrk); int vcl_sapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds); +int vcl_sapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair); +int vcl_sapi_del_cert_key_pair (u32 ckpair_index); #endif /* SRC_VCL_VCL_PRIVATE_H_ */ diff --git a/src/vcl/vcl_sapi.c b/src/vcl/vcl_sapi.c index 84d56af576b..981257ede8d 100644 --- a/src/vcl/vcl_sapi.c +++ b/src/vcl/vcl_sapi.c @@ -356,6 +356,115 @@ vcl_sapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds) return 0; } +int +vcl_sapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair) +{ + u32 cert_len = ckpair->cert_len, key_len = ckpair->key_len, certkey_len; + vcl_worker_t *wrk = vcl_worker_get_current (); + app_sapi_msg_t _msg = { 0 }, *msg = &_msg; + app_sapi_cert_key_add_del_msg_t *mp; + app_sapi_msg_t _rmp, *rmp = &_rmp; + clib_error_t *err; + clib_socket_t *cs; + u8 *certkey = 0; + int rv = -1; + + msg->type = APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY; + mp = &msg->cert_key_add_del; + mp->context = wrk->wrk_index; + mp->cert_len = cert_len; + mp->certkey_len = cert_len + key_len; + mp->is_add = 1; + + certkey_len = cert_len + key_len; + vec_validate (certkey, certkey_len - 1); + clib_memcpy_fast (certkey, ckpair->cert, cert_len); + clib_memcpy_fast (certkey + cert_len, ckpair->key, key_len); + + cs = &wrk->app_api_sock; + err = clib_socket_sendmsg (cs, msg, sizeof (*msg), 0, 0); + if (err) + { + clib_error_report (err); + goto done; + } + + err = clib_socket_sendmsg (cs, certkey, certkey_len, 0, 0); + if (err) + { + clib_error_report (err); + goto done; + } + + /* + * Wait for reply and process it + */ + err = clib_socket_recvmsg (cs, rmp, sizeof (*rmp), 0, 0); + if (err) + { + clib_error_report (err); + goto done; + } + + if (rmp->type != APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY_REPLY) + { + clib_warning ("unexpected reply type %u", rmp->type); + goto done; + } + + if (!rmp->cert_key_add_del_reply.retval) + rv = rmp->cert_key_add_del_reply.index; + +done: + + return rv; +} + +int +vcl_sapi_del_cert_key_pair (u32 ckpair_index) +{ + vcl_worker_t *wrk = vcl_worker_get_current (); + app_sapi_msg_t _msg = { 0 }, *msg = &_msg; + app_sapi_cert_key_add_del_msg_t *mp; + app_sapi_msg_t _rmp, *rmp = &_rmp; + clib_error_t *err; + clib_socket_t *cs; + + msg->type = APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY; + mp = &msg->cert_key_add_del; + mp->context = wrk->wrk_index; + mp->index = ckpair_index; + + cs = &wrk->app_api_sock; + err = clib_socket_sendmsg (cs, &msg, sizeof (msg), 0, 0); + if (err) + { + clib_error_report (err); + return -1; + } + + /* + * Wait for reply and process it + */ + err = clib_socket_recvmsg (cs, rmp, sizeof (*rmp), 0, 0); + if (err) + { + clib_error_report (err); + return -1; + } + + if (rmp->type != APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY_REPLY) + { + clib_warning ("unexpected reply type %u", rmp->type); + return -1; + } + + if (rmp->cert_key_add_del_reply.retval) + return -1; + + return 0; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 62aeff636b8..c718c2fcc97 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -4388,22 +4388,18 @@ 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); + return vcl_sapi_add_cert_key_pair (ckpair); + else + 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); + return vcl_sapi_del_cert_key_pair (ckpair_index); + else + return vcl_bapi_del_cert_key_pair (ckpair_index); } /* diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index b10dd6c150d..ca8dc38c4e1 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -817,6 +817,8 @@ typedef enum app_sapi_msg_type APP_SAPI_MSG_TYPE_ADD_DEL_WORKER, APP_SAPI_MSG_TYPE_ADD_DEL_WORKER_REPLY, APP_SAPI_MSG_TYPE_SEND_FDS, + APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY, + APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY_REPLY, } __clib_packed app_sapi_msg_type_e; typedef struct app_sapi_attach_msg_ @@ -861,6 +863,22 @@ typedef struct app_sapi_worker_add_del_reply_msg_ u8 is_add; } __clib_packed app_sapi_worker_add_del_reply_msg_t; +typedef struct app_sapi_cert_key_add_del_msg_ +{ + u32 context; + u32 index; + u16 cert_len; + u16 certkey_len; + u8 is_add; +} __clib_packed app_sapi_cert_key_add_del_msg_t; + +typedef struct app_sapi_cert_key_add_del_reply_msg_ +{ + u32 context; + i32 retval; + u32 index; +} __clib_packed app_sapi_cert_key_add_del_reply_msg_t; + typedef struct app_sapi_msg_ { app_sapi_msg_type_e type; @@ -870,6 +888,8 @@ typedef struct app_sapi_msg_ app_sapi_attach_reply_msg_t attach_reply; app_sapi_worker_add_del_msg_t worker_add_del; app_sapi_worker_add_del_reply_msg_t worker_add_del_reply; + app_sapi_cert_key_add_del_msg_t cert_key_add_del; + app_sapi_cert_key_add_del_reply_msg_t cert_key_add_del_reply; }; } __clib_packed app_sapi_msg_t; diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 00e67dcd2d0..e420099e308 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -1488,6 +1488,83 @@ done: clib_socket_sendmsg (cs, &msg, sizeof (msg), fds, n_fds); } +static void +sapi_add_del_cert_key_handler (app_namespace_t *app_ns, clib_socket_t *cs, + app_sapi_cert_key_add_del_msg_t *mp) +{ + vnet_app_add_cert_key_pair_args_t _a, *a = &_a; + app_sapi_cert_key_add_del_reply_msg_t *rmp; + app_sapi_msg_t msg = { 0 }; + int rv = 0; + + if (mp->is_add) + { + const u32 max_certkey_len = 2e4, max_cert_len = 1e4, max_key_len = 1e4; + clib_error_t *err; + u8 *certkey = 0; + u32 key_len; + + if (mp->certkey_len > max_certkey_len) + { + rv = SESSION_E_INVALID; + goto send_reply; + } + + vec_validate (certkey, mp->certkey_len - 1); + err = clib_socket_recvmsg (cs, certkey, mp->certkey_len, 0, 0); + if (err) + { + clib_error_report (err); + clib_error_free (err); + rv = SESSION_E_INVALID; + goto send_reply; + } + + if (mp->cert_len > max_cert_len) + { + rv = SESSION_E_INVALID; + goto send_reply; + } + + if (mp->certkey_len < mp->cert_len) + { + rv = SESSION_E_INVALID; + goto send_reply; + } + + key_len = mp->certkey_len - mp->cert_len; + if (key_len > max_key_len) + { + rv = SESSION_E_INVALID; + goto send_reply; + } + + clib_memset (a, 0, sizeof (*a)); + a->cert = certkey; + a->key = certkey + mp->cert_len; + a->cert_len = mp->cert_len; + a->key_len = key_len; + rv = vnet_app_add_cert_key_pair (a); + + vec_free (certkey); + } + else + { + rv = vnet_app_del_cert_key_pair (mp->index); + } + +send_reply: + + msg.type = APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY_REPLY; + rmp = &msg.cert_key_add_del_reply; + rmp->retval = rv; + rmp->context = mp->context; + if (!rv && mp->is_add) + rmp->index = a->index; + + clib_socket_sendmsg (cs, &msg, sizeof (msg), 0, 0); +} + static void sapi_socket_detach (app_namespace_t * app_ns, clib_socket_t * cs) { @@ -1548,6 +1625,9 @@ sapi_sock_read_ready (clib_file_t * cf) case APP_SAPI_MSG_TYPE_ADD_DEL_WORKER: sapi_add_del_worker_handler (app_ns, cs, &msg.worker_add_del); break; + case APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY: + sapi_add_del_cert_key_handler (app_ns, cs, &msg.cert_key_add_del); + break; default: clib_warning ("app wrk %u unknown message type: %u", handle->aah_app_wrk_index, msg.type); diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h index 246978e0ac3..0cf463d569d 100644 --- a/src/vnet/session/session_types.h +++ b/src/vnet/session/session_types.h @@ -469,6 +469,7 @@ STATIC_ASSERT (sizeof (session_dgram_hdr_t) == (SESSION_CONN_ID_LEN + 8), _ (PORTINUSE, "lcl port in use") \ _ (IPINUSE, "ip in use") \ _ (ALREADY_LISTENING, "ip port pair already listened on") \ + _ (INVALID, "invalid value") \ _ (INVALID_RMT_IP, "invalid remote ip") \ _ (INVALID_APPWRK, "invalid app worker") \ _ (INVALID_NS, "invalid namespace") \ -- 2.16.6