diff options
author | Nathan Skrzypczak <nathan.skrzypczak@gmail.com> | 2019-09-13 11:08:13 +0200 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2019-10-09 01:09:11 +0000 |
commit | 79f89537c6fd3baeac03354a3381f42895fe2ca8 (patch) | |
tree | 967f83e5a26a4fcfb7857c122d2217a1094f9942 | |
parent | ff5a9b6ecd744ff5c42e6c2388dd31a338ea6a0c (diff) |
session: Add certificate store
Type: feature
This changes the behavior of both API calls
APPLICATION_TLS_CERT_ADD & APPLICATION_TLS_KEY_ADD
certificates and keys aren't bound to an app, they are
passed to it via connect / listen using the message
queue.
This should be followed by a per protocol (QUIC/TLS)
crypto_context store to save devrived structs
Change-Id: I36873bc8b63b5c72776c69e8cd9febc9cae31882
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
-rw-r--r-- | src/plugins/quic/quic.c | 18 | ||||
-rw-r--r-- | src/plugins/quic/quic.h | 3 | ||||
-rw-r--r-- | src/plugins/tlsmbedtls/tls_mbedtls.c | 18 | ||||
-rw-r--r-- | src/plugins/tlsopenssl/tls_openssl.c | 14 | ||||
-rw-r--r-- | src/vnet/session/application.c | 152 | ||||
-rw-r--r-- | src/vnet/session/application.h | 18 | ||||
-rw-r--r-- | src/vnet/session/application_interface.h | 23 | ||||
-rw-r--r-- | src/vnet/session/session.api | 40 | ||||
-rwxr-xr-x | src/vnet/session/session_api.c | 117 | ||||
-rw-r--r-- | src/vnet/session/session_node.c | 4 | ||||
-rw-r--r-- | src/vnet/session/session_types.h | 4 | ||||
-rw-r--r-- | src/vnet/tls/tls.c | 2 | ||||
-rw-r--r-- | src/vnet/tls/tls.h | 1 |
13 files changed, 330 insertions, 84 deletions
diff --git a/src/plugins/quic/quic.c b/src/plugins/quic/quic.c index e9df9ff5025..6648a413e65 100644 --- a/src/plugins/quic/quic.c +++ b/src/plugins/quic/quic.c @@ -855,11 +855,12 @@ quic_encrypt_ticket_cb (ptls_encrypt_ticket_t * _self, ptls_t * tls, } static void -quic_store_quicly_ctx (application_t * app, u8 is_client) +quic_store_quicly_ctx (application_t * app, u32 cert_key_index) { quic_main_t *qm = &quic_main; quicly_context_t *quicly_ctx; ptls_iovec_t key_vec; + app_cert_key_pair_t *ckpair; if (app->quicly_ctx) return; @@ -910,16 +911,15 @@ quic_store_quicly_ctx (application_t * app, u8 is_client) quicly_new_default_cid_encryptor (&ptls_openssl_bfecb, &ptls_openssl_aes128ecb, &ptls_openssl_sha256, key_vec); - if (is_client) - return; - if (app->tls_key != NULL && app->tls_cert != NULL) + + ckpair = app_cert_key_pair_get_if_valid (cert_key_index); + if (ckpair && ckpair->key != NULL && ckpair->cert != NULL) { - if (load_bio_private_key (quicly_ctx->tls, (char *) app->tls_key)) + if (load_bio_private_key (quicly_ctx->tls, (char *) ckpair->key)) { QUIC_DBG (1, "failed to read private key from app configuration\n"); } - if (load_bio_certificate_chain (quicly_ctx->tls, - (char *) app->tls_cert)) + if (load_bio_certificate_chain (quicly_ctx->tls, (char *) ckpair->cert)) { QUIC_DBG (1, "failed to load certificate\n"); } @@ -1071,7 +1071,7 @@ quic_connect_connection (session_endpoint_cfg_t * sep) ctx->parent_app_id = app_wrk->app_index; cargs->sep_ext.ns_index = app->ns_index; - quic_store_quicly_ctx (app, 1 /* is client */ ); + quic_store_quicly_ctx (app, ctx->ckpair_index); /* Also store it in ctx for convenience * Waiting for crypto_ctx logic */ ctx->quicly_ctx = (quicly_context_t *) app->quicly_ctx; @@ -1163,7 +1163,7 @@ quic_start_listen (u32 quic_listen_session_index, transport_endpoint_t * tep) app = application_get (app_wrk->app_index); QUIC_DBG (2, "Called quic_start_listen for app %d", app_wrk->app_index); - quic_store_quicly_ctx (app, 0 /* is_client */ ); + quic_store_quicly_ctx (app, sep->ckpair_index); sep->transport_proto = TRANSPORT_PROTO_UDPC; clib_memset (args, 0, sizeof (*args)); diff --git a/src/plugins/quic/quic.h b/src/plugins/quic/quic.h index 312ffcba1cb..85c78dd7871 100644 --- a/src/plugins/quic/quic.h +++ b/src/plugins/quic/quic.h @@ -121,8 +121,9 @@ typedef struct quic_ctx_ u32 timer_handle; u32 parent_app_wrk_id; u32 parent_app_id; - u8 flags; + u32 ckpair_index; quicly_context_t *quicly_ctx; + u8 flags; } quic_ctx_t; /* Make sure our custom fields don't overlap with the fields we use in diff --git a/src/plugins/tlsmbedtls/tls_mbedtls.c b/src/plugins/tlsmbedtls/tls_mbedtls.c index 73112323f0e..7a2abaf39b9 100644 --- a/src/plugins/tlsmbedtls/tls_mbedtls.c +++ b/src/plugins/tlsmbedtls/tls_mbedtls.c @@ -276,8 +276,7 @@ mbedtls_ctx_init_server (tls_ctx_t * ctx) { mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx; mbedtls_main_t *mm = &mbedtls_main; - app_worker_t *app_wrk; - application_t *app; + app_cert_key_pair_t *ckpair; void *ctx_ptr; int rv; @@ -289,12 +288,11 @@ mbedtls_ctx_init_server (tls_ctx_t * ctx) /* * 1. Cert */ - app_wrk = app_worker_get (ctx->parent_app_wrk_index); - if (!app_wrk) + ckpair = app_cert_key_pair_get_if_valid (ctx->ckpair_index); + if (!ckpair) return -1; - app = application_get (app_wrk->app_index); - if (!app->tls_cert || !app->tls_key) + if (!ckpair->cert || !ckpair->key) { TLS_DBG (1, " failed\n ! tls cert and/or key not configured %d", ctx->parent_app_wrk_index); @@ -302,8 +300,8 @@ mbedtls_ctx_init_server (tls_ctx_t * ctx) } rv = mbedtls_x509_crt_parse (&mc->srvcert, - (const unsigned char *) app->tls_cert, - vec_len (app->tls_cert)); + (const unsigned char *) ckpair->cert, + vec_len (ckpair->cert)); if (rv != 0) { TLS_DBG (1, " failed\n ! mbedtls_x509_crt_parse returned %d", rv); @@ -311,8 +309,8 @@ mbedtls_ctx_init_server (tls_ctx_t * ctx) } rv = mbedtls_pk_parse_key (&mc->pkey, - (const unsigned char *) app->tls_key, - vec_len (app->tls_key), NULL, 0); + (const unsigned char *) ckpair->key, + vec_len (ckpair->key), NULL, 0); if (rv != 0) { TLS_DBG (1, " failed\n ! mbedtls_pk_parse_key returned %d", rv); diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c index 589d76de860..c383cf3561d 100644 --- a/src/plugins/tlsopenssl/tls_openssl.c +++ b/src/plugins/tlsopenssl/tls_openssl.c @@ -592,7 +592,6 @@ openssl_ctx_init_client (tls_ctx_t * ctx) static int openssl_start_listen (tls_ctx_t * lctx) { - application_t *app; const SSL_METHOD *method; SSL_CTX *ssl_ctx; int rv; @@ -601,17 +600,16 @@ openssl_start_listen (tls_ctx_t * lctx) EVP_PKEY *pkey; u32 olc_index; openssl_listen_ctx_t *olc; - app_worker_t *app_wrk; + app_cert_key_pair_t *ckpair; long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION; openssl_main_t *om = &openssl_main; - app_wrk = app_worker_get (lctx->parent_app_wrk_index); - if (!app_wrk) + ckpair = app_cert_key_pair_get_if_valid (lctx->ckpair_index); + if (!ckpair) return -1; - app = application_get (app_wrk->app_index); - if (!app->tls_cert || !app->tls_key) + if (!ckpair->cert || !ckpair->key) { TLS_DBG (1, "tls cert and/or key not configured %d", lctx->parent_app_wrk_index); @@ -646,7 +644,7 @@ openssl_start_listen (tls_ctx_t * lctx) * Set the key and cert */ cert_bio = BIO_new (BIO_s_mem ()); - BIO_write (cert_bio, app->tls_cert, vec_len (app->tls_cert)); + BIO_write (cert_bio, ckpair->cert, vec_len (ckpair->cert)); srvcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL); if (!srvcert) { @@ -657,7 +655,7 @@ openssl_start_listen (tls_ctx_t * lctx) BIO_free (cert_bio); cert_bio = BIO_new (BIO_s_mem ()); - BIO_write (cert_bio, app->tls_key, vec_len (app->tls_key)); + BIO_write (cert_bio, ckpair->key, vec_len (ckpair->key)); pkey = PEM_read_bio_PrivateKey (cert_bio, NULL, NULL, NULL); if (!pkey) { diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 583c4b055ee..82c890f56ce 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -591,8 +591,6 @@ application_free (application_t * app) if (application_is_builtin (app)) application_name_table_del (app); vec_free (app->name); - vec_free (app->tls_cert); - vec_free (app->tls_key); pool_put (app_main.app_pool, app); } @@ -1305,24 +1303,20 @@ application_get_segment_manager_properties (u32 app_index) clib_error_t * vnet_app_add_tls_cert (vnet_app_add_tls_cert_args_t * a) { - application_t *app; - app = application_get (a->app_index); - if (!app) - return clib_error_return_code (0, VNET_API_ERROR_APPLICATION_NOT_ATTACHED, - 0, "app %u doesn't exist", a->app_index); - app->tls_cert = vec_dup (a->cert); + /* 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) { - application_t *app; - app = application_get (a->app_index); - if (!app) - return clib_error_return_code (0, VNET_API_ERROR_APPLICATION_NOT_ATTACHED, - 0, "app %u doesn't exist", a->app_index); - app->tls_key = vec_dup (a->key); + /* 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; } @@ -1376,6 +1370,22 @@ application_format_connects (application_t * app, int verbose) } u8 * +format_cert_key_pair (u8 * s, va_list * args) +{ + app_cert_key_pair_t *ckpair = va_arg (*args, app_cert_key_pair_t *); + int key_len = 0, cert_len = 0; + cert_len = vec_len (ckpair->cert); + key_len = vec_len (ckpair->key); + if (ckpair->cert_key_index == 0) + s = format (s, "DEFAULT (cert:%d, key:%d)", cert_len, key_len); + else + s = + format (s, "%d (cert:%d, key:%d)", ckpair->cert_key_index, cert_len, + key_len); + return s; +} + +u8 * format_application (u8 * s, va_list * args) { application_t *app = va_arg (*args, application_t *); @@ -1460,6 +1470,21 @@ application_format_all_clients (vlib_main_t * vm, int verbose) } static clib_error_t * +show_certificate_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + app_cert_key_pair_t *ckpair; + session_cli_return_if_not_enabled (); + + /* *INDENT-OFF* */ + pool_foreach (ckpair, app_main.cert_key_pair_store, ({ + vlib_cli_output (vm, "%U", format_cert_key_pair, ckpair); + })); + /* *INDENT-ON* */ + return 0; +} + +static clib_error_t * show_app_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { @@ -1521,13 +1546,112 @@ show_app_command_fn (vlib_main_t * vm, unformat_input_t * input, return 0; } +/* + * Certificate store + * + */ + +static app_cert_key_pair_t * +app_cert_key_pair_alloc () +{ + app_cert_key_pair_t *ckpair; + pool_get (app_main.cert_key_pair_store, ckpair); + clib_memset (ckpair, 0, sizeof (*ckpair)); + ckpair->cert_key_index = ckpair - app_main.cert_key_pair_store; + return ckpair; +} + +app_cert_key_pair_t * +app_cert_key_pair_get_if_valid (u32 index) +{ + if (pool_is_free_index (app_main.cert_key_pair_store, index)) + return 0; + return app_cert_key_pair_get (index); +} + +app_cert_key_pair_t * +app_cert_key_pair_get (u32 index) +{ + return pool_elt_at_index (app_main.cert_key_pair_store, index); +} + +app_cert_key_pair_t * +app_cert_key_pair_get_default () +{ + /* To maintain legacy bapi */ + return app_cert_key_pair_get (0); +} + +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); + a->index = ckpair->cert_key_index; + return 0; +} + +int +vent_app_add_cert_key_interest (u32 index, u32 app_index) +{ + app_cert_key_pair_t *ckpair; + if (!(ckpair = app_cert_key_pair_get_if_valid (index))) + return -1; + vec_add1 (ckpair->app_interests, app_index); + return 0; +} + +int +vnet_app_del_cert_key_pair (u32 index) +{ + app_cert_key_pair_t *ckpair; + application_t *app; + u32 *app_index; + + if (!(ckpair = app_cert_key_pair_get_if_valid (index))) + return (VNET_API_ERROR_INVALID_VALUE); + + vec_foreach (app_index, ckpair->app_interests) + { + if ((app = application_get_if_valid (*app_index)) + && app->cb_fns.app_cert_key_pair_delete_callback) + app->cb_fns.app_cert_key_pair_delete_callback (ckpair); + } + + vec_free (ckpair->cert); + vec_free (ckpair->key); + pool_put (app_main.cert_key_pair_store, ckpair); + return 0; +} + +clib_error_t * +cert_key_pair_store_init (vlib_main_t * vm) +{ + /* Add a certificate with index 0 to support legacy apis */ + (void) app_cert_key_pair_alloc (); + return 0; +} + /* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (cert_key_pair_store_init) = +{ + .runs_after = VLIB_INITS("unix_physmem_init"), +}; + VLIB_CLI_COMMAND (show_app_command, static) = { .path = "show app", .short_help = "show app [server|client] [verbose]", .function = show_app_command_fn, }; + +VLIB_CLI_COMMAND (show_certificate_command, static) = +{ + .path = "show app certificate", + .short_help = "list app certs and keys present in store", + .function = show_certificate_command_fn, +}; /* *INDENT-ON* */ /* diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h index 9ec1055bbbc..a853c3cb73a 100644 --- a/src/vnet/session/application.h +++ b/src/vnet/session/application.h @@ -111,16 +111,6 @@ typedef struct application_ /** Pool of listeners for the app */ app_listener_t *listeners; - /* - * TLS & QUIC Specific - */ - - /** Certificate to be used for listen sessions */ - u8 *tls_cert; - - /** PEM encoded key */ - u8 *tls_key; - /** Preferred tls engine */ u8 tls_engine; @@ -144,6 +134,11 @@ typedef struct app_main_ * Hash table of builtin apps by name */ uword *app_by_name; + + /** + * Pool from which we allocate certificates (key, cert) + */ + app_cert_key_pair_t *cert_key_pair_store; } app_main_t; typedef struct app_init_args_ @@ -284,6 +279,9 @@ int vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a); uword unformat_application_proto (unformat_input_t * input, va_list * args); +app_cert_key_pair_t *app_cert_key_pair_get (u32 index); +app_cert_key_pair_t *app_cert_key_pair_get_if_valid (u32 index); +app_cert_key_pair_t *app_cert_key_pair_get_default (); /* Needed while we support both bapi and mq ctrl messages */ int mq_send_session_bound_cb (u32 app_wrk_index, u32 api_context, diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index 17f7ef209e5..fa6206a5279 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -21,6 +21,14 @@ #include <vnet/tls/tls_test.h> #include <svm/fifo_segment.h> +typedef struct certificate_ +{ + u32 *app_interests; /* vec of application index asking for deletion cb */ + u32 cert_key_index; /* index in cert & key pool */ + u8 *key; + u8 *cert; +} app_cert_key_pair_t; + typedef struct _stream_session_cb_vft { /** Notify server of new segment */ @@ -57,6 +65,9 @@ typedef struct _stream_session_cb_vft /** Direct TX callback for built-in application */ int (*builtin_app_tx_callback) (session_t * session); + /** Cert and key pair delete notification */ + int (*app_cert_key_pair_delete_callback) (app_cert_key_pair_t * ckpair); + } session_cb_vft_t; #define foreach_app_init_args \ @@ -158,6 +169,13 @@ typedef enum tls_engine_type_ TLS_N_ENGINES } tls_engine_type_t; +typedef struct _vnet_app_add_cert_key_pair_args_ +{ + u8 *cert; + u8 *key; + u32 index; +} vnet_app_add_cert_key_pair_args_t; + /* Application attach options */ typedef enum { @@ -236,6 +254,9 @@ 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); +int vent_app_add_cert_key_interest (u32 index, u32 app_index); /* Ask for app cb on pair deletion */ typedef struct app_session_transport_ { @@ -273,6 +294,7 @@ typedef struct session_listen_msg_ u8 proto; u8 is_ip4; ip46_address_t ip; + u32 ckpair_index; } __clib_packed session_listen_msg_t; typedef struct session_listen_uri_msg_ @@ -345,6 +367,7 @@ typedef struct session_connect_msg_ u8 hostname_len; u8 hostname[16]; u64 parent_handle; + u32 ckpair_index; } __clib_packed session_connect_msg_t; typedef struct session_connect_uri_msg_ diff --git a/src/vnet/session/session.api b/src/vnet/session/session.api index 6f208ff5b0e..33e53419a8d 100644 --- a/src/vnet/session/session.api +++ b/src/vnet/session/session.api @@ -108,7 +108,46 @@ define app_attach_reply { u64 segment_handle; }; +/** \brief Add certificate and key + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param engine - crypto engine + @param cert_len - cert length (comes first) + @param certkey_len - cert and key length + @param certkey - cert & key data (due to API limitation) +*/ +define app_add_cert_key_pair { + u32 client_index; + u32 context; + u16 cert_len; + u16 certkey_len; + u8 certkey[certkey_len]; +}; + +/** \brief Add certificate and key + @param context - sender context, to match reply w/ request + @param retval - return code for the request + @param index - index in certificate store +*/ +define app_add_cert_key_pair_reply { + u32 context; + i32 retval; + u32 index; +}; + +/** \brief Delete certificate and key + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param index - index in certificate store +*/ +autoreply define app_del_cert_key_pair { + u32 client_index; + u32 context; + u32 index; +}; + /** \brief Application add TLS certificate + ### WILL BE DEPRECATED POST 20.01 ### @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param cert_len - certificate length @@ -123,6 +162,7 @@ autoreply define application_tls_cert_add { }; /** \brief Application add TLS key + ### WILL BE DEPRECATED POST 20.01 ### @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param key_len - certificate length diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index c55aab33541..c17d98c0517 100755 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -59,6 +59,8 @@ _(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) \ static int @@ -1059,7 +1061,7 @@ vl_api_app_worker_add_del_t_handler (vl_api_app_worker_add_del_t * mp) application_t *app; u8 fd_flags = 0; - if (!session_main_is_enabled ()) + if (session_main_is_enabled () == 0) { rv = VNET_API_ERROR_FEATURE_DISABLED; goto done; @@ -1138,7 +1140,7 @@ vl_api_app_namespace_add_del_t_handler (vl_api_app_namespace_add_del_t * mp) u32 appns_index = 0; u8 *ns_id = 0; int rv = 0; - if (!session_main_is_enabled ()) + if (session_main_is_enabled () == 0) { rv = VNET_API_ERROR_FEATURE_DISABLED; goto done; @@ -1356,16 +1358,84 @@ vl_api_session_rules_dump_t_handler (vl_api_one_map_server_dump_t * mp) } static void +vl_api_app_add_cert_key_pair_t_handler (vl_api_app_add_cert_key_pair_t * mp) +{ + vl_api_app_add_cert_key_pair_reply_t *rmp; + vnet_app_add_cert_key_pair_args_t _a, *a = &_a; + u32 certkey_len, key_len, cert_len; + int rv = 0; + if (session_main_is_enabled () == 0) + { + rv = VNET_API_ERROR_FEATURE_DISABLED; + goto done; + } + + cert_len = clib_net_to_host_u16 (mp->cert_len); + if (cert_len > 10000) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto done; + } + + certkey_len = clib_net_to_host_u16 (mp->certkey_len); + if (certkey_len < cert_len) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto done; + } + + key_len = certkey_len - cert_len; + if (key_len > 10000) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto done; + } + + 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); + rv = vnet_app_add_cert_key_pair (a); + vec_free (a->cert); + vec_free (a->key); + +done: + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_APP_ADD_CERT_KEY_PAIR_REPLY, ({ + if (!rv) + rmp->index = a->index; + })); + /* *INDENT-ON* */ +} + +static void +vl_api_app_del_cert_key_pair_t_handler (vl_api_app_del_cert_key_pair_t * mp) +{ + vl_api_app_del_cert_key_pair_reply_t *rmp; + int rv = 0; + if (session_main_is_enabled () == 0) + { + rv = VNET_API_ERROR_FEATURE_DISABLED; + goto done; + } + rv = vnet_app_del_cert_key_pair (mp->index); + +done: + REPLY_MACRO (VL_API_APP_ADD_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_app_namespace_add_del_reply_t *rmp; - vnet_app_add_tls_cert_args_t _a, *a = &_a; - clib_error_t *error; + 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 ()) + if (session_main_is_enabled () == 0) { rv = VNET_API_ERROR_FEATURE_DISABLED; goto done; @@ -1375,37 +1445,31 @@ vl_api_application_tls_cert_add_t_handler (vl_api_application_tls_cert_add_t * rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED; goto done; } - clib_memset (a, 0, sizeof (*a)); - a->app_index = app->app_index; cert_len = clib_net_to_host_u16 (mp->cert_len); if (cert_len > 10000) { rv = VNET_API_ERROR_INVALID_VALUE; goto done; } - vec_validate (a->cert, cert_len); - clib_memcpy_fast (a->cert, mp->cert, cert_len); - if ((error = vnet_app_add_tls_cert (a))) - { - rv = clib_error_get_code (error); - clib_error_report (error); - } - vec_free (a->cert); + 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_app_namespace_add_del_reply_t *rmp; - vnet_app_add_tls_key_args_t _a, *a = &_a; - clib_error_t *error; + 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 ()) + if (session_main_is_enabled () == 0) { rv = VNET_API_ERROR_FEATURE_DISABLED; goto done; @@ -1415,22 +1479,15 @@ vl_api_application_tls_key_add_t_handler (vl_api_application_tls_key_add_t * rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED; goto done; } - clib_memset (a, 0, sizeof (*a)); - a->app_index = app->app_index; key_len = clib_net_to_host_u16 (mp->key_len); if (key_len > 10000) { rv = VNET_API_ERROR_INVALID_VALUE; goto done; } - vec_validate (a->key, key_len); - clib_memcpy_fast (a->key, mp->key, key_len); - if ((error = vnet_app_add_tls_key (a))) - { - rv = clib_error_get_code (error); - clib_error_report (error); - } - vec_free (a->key); + 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); } diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c index e2e98eba19f..fde1931aaf9 100644 --- a/src/vnet/session/session_node.c +++ b/src/vnet/session/session_node.c @@ -54,6 +54,7 @@ session_mq_listen_handler (void *data) a->sep.fib_index = mp->vrf; a->sep.sw_if_index = ENDPOINT_INVALID_INDEX; a->sep.transport_proto = mp->proto; + a->sep_ext.ckpair_index = mp->ckpair_index; a->app_index = app->app_index; a->wrk_map_index = mp->wrk_index; @@ -112,6 +113,7 @@ session_mq_connect_handler (void *data) a->sep.peer.fib_index = mp->vrf; a->sep.peer.sw_if_index = ENDPOINT_INVALID_INDEX; a->sep_ext.parent_handle = mp->parent_handle; + a->sep_ext.ckpair_index = mp->ckpair_index; if (mp->hostname_len) { vec_validate (a->sep_ext.hostname, mp->hostname_len - 1); @@ -311,7 +313,7 @@ session_mq_reset_reply_handler (void *data) app_wrk = app_worker_get (s->app_wrk_index); if (!app_wrk || app_wrk->app_index != app->app_index) { - clib_warning ("App % does not own handle 0x%lx!", app->app_index, + clib_warning ("App %u does not own handle 0x%lx!", app->app_index, mp->handle); return; } diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h index 03f7096c4b8..bb309f2f31c 100644 --- a/src/vnet/session/session_types.h +++ b/src/vnet/session/session_types.h @@ -44,6 +44,7 @@ typedef struct _session_endpoint_cfg u8 original_tp; u8 *hostname; u64 parent_handle; + u32 ckpair_index; } session_endpoint_cfg_t; #define SESSION_IP46_ZERO \ @@ -83,7 +84,8 @@ typedef struct _session_endpoint_cfg .app_wrk_index = ENDPOINT_INVALID_INDEX, \ .opaque = ENDPOINT_INVALID_INDEX, \ .hostname = 0, \ - .parent_handle = SESSION_INVALID_HANDLE \ + .parent_handle = SESSION_INVALID_HANDLE, \ + .ckpair_index = 0 \ } #define session_endpoint_to_transport(_sep) ((transport_endpoint_t *)_sep) diff --git a/src/vnet/tls/tls.c b/src/vnet/tls/tls.c index 4fff72f1cda..c512517f9e5 100644 --- a/src/vnet/tls/tls.c +++ b/src/vnet/tls/tls.c @@ -412,6 +412,7 @@ tls_session_accept_callback (session_t * tls_session) ctx->tls_session_handle = session_handle (tls_session); ctx->listener_ctx_index = tls_listener->opaque; ctx->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP; + ctx->ckpair_index = lctx->ckpair_index; /* Preallocate app session. Avoids allocating a session post handshake * on tls_session rx and potentially invalidating the session pool */ @@ -625,6 +626,7 @@ tls_start_listen (u32 app_listener_index, transport_endpoint_t * tep) lctx->app_session_handle = listen_session_get_handle (app_listener); lctx->tcp_is_ip4 = sep->is_ip4; lctx->tls_ctx_engine = engine_type; + lctx->ckpair_index = sep->ckpair_index; if (tls_vfts[engine_type].ctx_start_listen (lctx)) { diff --git a/src/vnet/tls/tls.h b/src/vnet/tls/tls.h index eaba3c085b6..8b1db9890cb 100644 --- a/src/vnet/tls/tls.h +++ b/src/vnet/tls/tls.h @@ -79,6 +79,7 @@ typedef struct tls_ctx_ u8 app_closed; u8 no_app_session; u8 *srv_hostname; + u32 ckpair_index; } tls_ctx_t; typedef struct tls_main_ |